我正在创建单元测试,以帮助构建一些代码,这些代码将接受并排队(如果需要)来自我的控制器的入站请求。
在我的单元测试中,我希望同时启动两行代码,尽管调用之间有2秒的延迟。这允许我的逻辑的第一个分支被触发,然后在第二次调用时,因为已经看到传递的数据使用逻辑的备用分支。
我已经走近了,但感觉很乱。我正在使用以下内容,它会立即关闭我的第一个电话并转到后续的代码行。
Task.Factory.StartNew(() => stubbedQueueHandler.QueueProcessor(setupModel));
Thread.Sleep(2000);
//second call
stubbedQueueHandler.QueueProcessor(setupModel);
await Task.Delay(10000);
然而,单元测试在第一次调用结束之前结束,这反过来又杀死了整个过程。允许第一个调用完成的唯一方法是放置一个await Task.Delay()
行来完成这个操作。
我可以理解为什么会这样做,因为我已经有效地切换了电话而没有期待回复。我不想开始使用任务延迟,我确信这只是我缺乏理解,这就是异步编程时的问题:o)。
答案 0 :(得分:4)
你需要的是捕获启动Task
的{{1}}并在第二次调用存根之后等待它:
QueueProcessor
这样,您可以确保在操作完成之前完成操作,前提是public async Task FooTestAsync()
{
var task = Task.Run(() => stubbedQueueHandler.QueueProcessor(setupModel));
await Task.Delay(2000);
stubbedQueueHandler.QueueProcessor(setupModel);
await task;
}
将同步阻塞,直到操作完成。
答案 1 :(得分:3)
您需要避免将Thread.Sleep()与异步代码一起使用。
请参阅Figure 5 The “Async Way” of Doing Things:
To Do This Instead of This Use This Retrieve the result of a background task Task.Wait or Task.Result await Wait for any task to complete Task.WaitAny await Task.WhenAny Retrieve the results of multiple tasks Task.WaitAll await Task.WhenAll Wait a period of time Thread.Sleep await Task.Delay
你应该避免混合异步和阻塞代码。混合的异步和阻塞代码可能导致死锁,更复杂的错误处理和意外阻塞上下文线程。