Task.Wait() 死锁 Xamarin.iOS NUnit 运行器

本文关键字:iOS NUnit 运行 Xamarin 死锁 Wait Task | 更新日期: 2023-09-27 18:33:07

我有一个类,其中包含一些这样的方法:

private Task Sleep()
{
    return Task.Delay(SleepDuration);
}
public async Task<User> Login(string username, string password)
{
    await Sleep();
    return new User { Id = 1, Username = username };
}

请注意,在我的测试期间,SleepDuration设置为 0。

如果我在 iOS NUnit 项目测试中调用以下内容:

myClass.Login("username", "password").Wait();

测试运行程序的 UI 将暂停且永远不会完成。如果我添加断点,代码永远不会到达await之后的行。相同的测试在 .Net 4.5 Mono 项目中的标准 NUnit 运行器中运行良好。它在我的应用程序中也可以正常工作,尽管我从不调用Wait并且始终使用 async/await。

有什么想法吗?我可以使用其他东西代替Task.Delay来防止死锁吗?我已经试过Task.Factory.StartNew(() => { })了。

Task.Wait() 死锁 Xamarin.iOS NUnit 运行器

NUnit 的现代版本为其单元测试提供了一个SynchronizationContext,以便它们可以支持async void单元测试。

当您阻止异步代码(即 Wait )时,此上下文很可能导致死锁。我有一篇博客文章详细描述了交互。请注意,仅当 Task.Delay 返回尚未完成的Task时,才会发生此死锁;对于极短的延迟,无论Task在到达Wait时是否完成,都会存在竞争条件。

我建议您在单元测试中使用await,并使测试方法async Task