在C#中,我有以下两个简单的示例:
[Test]
public void TestWait()
{
var t = Task.Factory.StartNew(() =>
{
Console.WriteLine("Start");
Task.Delay(5000).Wait();
Console.WriteLine("Done");
});
t.Wait();
Console.WriteLine("All done");
}
[Test]
public void TestAwait()
{
var t = Task.Factory.StartNew(async () =>
{
Console.WriteLine("Start");
await Task.Delay(5000);
Console.WriteLine("Done");
});
t.Wait();
Console.WriteLine("All done");
}第一个示例创建了一个打印"Start“的任务,等待5秒打印"Done”,然后结束任务。我等待任务完成,然后打印"All done“。当我运行测试时,它会按预期运行。
第二个测试应该具有相同的行为,除了任务内部的等待应该是非阻塞的,因为使用了async和await。但这个测试只是打印"Start“,然后立即打印"All done”和"Done“。
我不知道为什么我会有这样的行为:I‘如果有任何帮助,我将非常感激:)
发布于 2014-11-07 18:34:50
第二个测试有两个嵌套的任务,您正在等待最外层的任务,要解决这个问题,您必须使用t.Result.Wait()。t.Result获得内部任务。
第二种方法大致相当于此:
public void TestAwait()
{
var t = Task.Factory.StartNew(() =>
{
Console.WriteLine("Start");
return Task.Factory.StartNew(() =>
{
Task.Delay(5000).Wait(); Console.WriteLine("Done");
});
});
t.Wait();
Console.WriteLine("All done");
}通过调用t.Wait(),您正在等待立即返回的最外层的任务。
处理这种情况的最终“正确”方法是完全放弃使用Wait,只使用await。将UI附加到异步代码后,Wait可能会导致deadlock issues。
[Test]
public async Task TestCorrect() //note the return type of Task. This is required to get the async test 'waitable' by the framework
{
await Task.Factory.StartNew(async () =>
{
Console.WriteLine("Start");
await Task.Delay(5000);
Console.WriteLine("Done");
}).Unwrap(); //Note the call to Unwrap. This automatically attempts to find the most Inner `Task` in the return type.
Console.WriteLine("All done");
}更好的做法是使用Task.Run来启动异步操作:
[TestMethod]
public async Task TestCorrect()
{
await Task.Run(async () => //Task.Run automatically unwraps nested Task types!
{
Console.WriteLine("Start");
await Task.Delay(5000);
Console.WriteLine("Done");
});
Console.WriteLine("All done");
}https://stackoverflow.com/questions/26798845
复制相似问题