为什么这个任务挂起?

时间:2016-09-02 07:52:17

标签: c# task

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

    Assert.AreEqual(1, i);
}

上述示例中的Task是什么原因永远等待?我应该Wait()如何处理任务,以免它挂起?

2 个答案:

答案 0 :(得分:8)

您没有开始 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);
}

答案 1 :(得分:4)

someTask.Wait"挂起"

通常有3个原因
  1. 您已捕获已捕获的同步上下文
  2. 根本没有同步上下文
  3. 您正在等待从未开始的任务
  4. 在第一个示例中,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,我宁愿将整个方法重写为异步:

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