如何正确使用C#单元测试FakeHttpContext解决同步调用报错问题
问题修复方案
错误根因
报错"Object synchronization method was called from an unsynchronized block of code."的核心原因是
ConfigureAwait(false)会打断同步上下文的延续,await执行完成后的后续代码(包括using块结束时自动触发的FakeHttpContext释放逻辑)不会回到最初创建FakeHttpContext的线程执行。而FakeHttpContext内部的销毁逻辑依赖原始线程持有的同步锁,跨线程释放不属于当前线程的锁就会触发该错误。
修复方案
直接移除await调用后的.ConfigureAwait(false)即可,让await后的代码回到原同步上下文执行,保证FakeHttpContext的释放操作在原始持有锁的线程完成,修复后的代码如下:
public async Task Test() { using (new FakeHttpContext.FakeHttpContext()) { BasketController _controller = new BasketController(); List<StockMovementModel> model = new List<StockMovementModel> { StockMovementFixtures.TestFixture() }; var result = await _controller.CreateTransfer(model, new Kendo.Mvc.UI.DataSourceRequest()); Assert.IsNotNull(result); } }
补充说明
ConfigureAwait(false)仅适用于不需要依赖原始同步上下文的异步场景,涉及上下文绑定对象(比如FakeHttpContext、HttpContext.Current、线程本地存储变量)的异步代码块不要随意添加该配置。- 如果存在性能要求必须使用
ConfigureAwait(false),可以将FakeHttpContext的生命周期调整为包裹整个异步逻辑的外层,或者使用支持异步上下文的HttpContext模拟类替代当前的FakeHttpContext实现。
内容的提问来源于stack exchange,提问作者AdamG31
相关产品推荐
相关产品推荐

