C# 单元测试和多个异步任务
我正在创建单元测试,以帮助构建一些代码,这些代码将接受并排队(如果需要)来自控制器的入站请求 在我的单元测试中,我希望两行代码几乎同时启动,尽管调用之间有2秒的延迟。这允许触发逻辑的第一个分支,然后在第二次调用时触发,因为已经看到传递的数据,所以使用了逻辑的备用分支 我已经接近了,但感觉很乱。我正在使用下面的代码,它会立即传递我的第一个调用,并转到后续的代码行C# 单元测试和多个异步任务,c#,asp.net,asynchronous,asp.net-web-api,async-await,C#,Asp.net,Asynchronous,Asp.net Web Api,Async Await,我正在创建单元测试,以帮助构建一些代码,这些代码将接受并排队(如果需要)来自控制器的入站请求 在我的单元测试中,我希望两行代码几乎同时启动,尽管调用之间有2秒的延迟。这允许触发逻辑的第一个分支,然后在第二次调用时触发,因为已经看到传递的数据,所以使用了逻辑的备用分支 我已经接近了,但感觉很乱。我正在使用下面的代码,它会立即传递我的第一个调用,并转到后续的代码行 Task.Factory.StartNew(() => stubbedQueueHandler.QueueProcessor(se
Task.Factory.StartNew(() => stubbedQueueHandler.QueueProcessor(setupModel));
Thread.Sleep(2000);
//second call
stubbedQueueHandler.QueueProcessor(setupModel);
await Task.Delay(10000);
然而,单元测试在第一次调用结束之前结束,这反过来又会终止进程。允许第一次调用完成的唯一方法是放置一个wait Task.Delay()
行,该行执行此操作
我明白它为什么这么做了,因为我已经有效地把电话交给了对方,而不期望对方会回复。我不想开始使用任务延迟,我确信这只是我不了解异步编程的问题所在:o)。您需要的是捕获启动
队列处理器的任务,并在第二次调用存根后等待它:
public async Task FooTestAsync()
{
var task = Task.Run(() => stubbedQueueHandler.QueueProcessor(setupModel));
await Task.Delay(2000);
stubbedQueueHandler.QueueProcessor(setupModel);
await task;
}
这样,您可以确保在操作完成之前完成操作,因为队列处理器将同步阻塞,直到其操作完成。您需要避免在异步代码中使用Thread.Sleep()
参考:
您应该避免混合使用异步代码和阻塞代码。混合异步和阻塞代码会导致死锁、更复杂的错误处理和上下文线程的意外阻塞
好的一点,一个我开始养成的坏习惯,将在未来把它扼杀在萌芽状态o) 这与其说是对老年退休金问题的回答,不如说是一种评论。
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