Второй тест состоит из двух вложенных задач, и вы ожидаете самого дальнего, чтобы исправить это, вы должны использовать 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
. Wait
может вызвать проблемы с блокировкой после присоединения пользовательского интерфейса к вашему асинхронному коду.
[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");
}