为什么这个任务挂起

本文关键字:挂起 任务 为什么 | 更新日期: 2023-09-27 18:05:13

[TestMethod]
public void Y()
{
    int i = 0;
    new Task(() => i++).Wait();
    Assert.AreEqual(1, i);
}

为什么上面例子中的Task永远等待?我应该如何为任务Wait(),使它不会挂起?

为什么这个任务挂起

您没有启动 Task。试试这个:

[TestMethod]
public void Y()
{
    int i = 0;
    Task task = new Task(() => i++);
    task.Start();
    task.Wait();
    Assert.AreEqual(1, i);
}

或者更好(如Damien建议的)使用Task.Run():

[TestMethod]
public void Y()
{
    int i = 0;
    Task.Run(() => i++).Wait();
    Assert.AreEqual(1, i);
}

someTask.Wait "挂起"一般有三个原因:

  1. 你已经锁定了被捕获的同步上下文
  2. 根本没有同步上下文
  3. 您正在等待一个从未启动的任务

在第一个例子中,windows窗体应用程序可能是一个场景,但[TestMethod]属性讲述了一个不同的故事。你可以通过使用.ConfigureAwait(false)来摆脱这种混乱,但是在走这条路之前,请仔细阅读这个主题。async/await表面上看起来很容易,但你正在踏入一个雷区。

在单元测试项目中,您需要一个测试运行器来处理发布到同步上下文的消息。如果您使用的测试运行器不这样做,那么可能是一个问题。

但是,在当前方法中,您没有启动任务。未开始的任务永远不会完成。

然而,如果你开始任务,你可能会以上述第2点结束。

结论:确保你启动了你的任务,如果仍然阻塞,看看你正在使用的单元测试框架。

启动任务:

var task = new Task(() => i++);
task.Start();
task.Wait();

另外,一般来说,除非你建立了一些框架来处理任务,否则你可能根本不应该使用new Task(...),而应该选择Task.Run:

Task.Run(() => i++).Wait();

如果你的测试运行器正确支持async/await,我宁愿重写整个方法为async:

[TestMethod]
public async Task Y()
{
    int i = 0;
    await new Task(() => i++);
    Assert.AreEqual(1, i);
}