4

我最近一直在尝试了解 C# 的新 async/await 和 Task.Run 功能。在这样做的过程中,我编写了一些简单的测试代码写入控制台,这样我就可以看到事情发生的顺序,在这里和那里抛出一个 Thread.Sleep 以确保事情真的按照我预期的顺序发生。

这是我的测试之一

[Test]
public void TaskRun()
{
    Console.WriteLine("Before");
    Task.Run(() => Console.WriteLine(_terminator.IWillBeBack()));
    Console.WriteLine("After");
}

具有以下终结者类:

public class Terminator
{
    public string IWillBeBack()
    {
        return "I will be back";
    }
}

由此我预计结果很可能是之前之后,然后我会回来。这确实是发生的事情。然后我对 IWillBeBack 方法进行了更改,让它休眠 3 秒。代码:

public class Terminator
{
    public string IWillBeBack()
    {
        Thread.Sleep(3000);
        return "I will be back";
    }
}

我预计结果仍然是之前之后,然后再过 3 秒我会回来。这不是发生的事情。我取而代之的是之前之后,但我永远不会回来

为什么是这样?

当我调试它时,它清楚地通过代码、睡眠和返回。我不需要在任何生产代码中以这种方式使用 Thread.Sleep,但我想对第二种情况下为什么我会回来没有写入控制台有一个模糊的理解。

4

2 回答 2

8

您的测试在尝试打印“我会回来”之前完成。你没有做任何事情等到完成。但是,根据测试运行程序,它的重定向Console.WriteLine可能在测试完成后立即断开连接。

如果您想看到它完成,请将您的测试更改为:

[Test]
public void TaskRun()
{
    Console.WriteLine("Before");
    var task = Task.Run(() => Console.WriteLine(_terminator.IWillBeBack()));
    Console.WriteLine("After");
    task.Wait();
}
于 2012-07-31T11:41:30.970 回答
1

如果您在 VS 2012 中使用 MS Test 框架,您也可以像这样编写测试

[TestMethod]
public async Task TaskRun()
{
    Console.WriteLine("Before");
    Task t = Task.Run(() => Console.WriteLine(IWillBeBack()));
    Console.WriteLine("After");
    await t;
}

private string IWillBeBack()
{
    Thread.Sleep(3000);
    return "I will be back";
}
于 2012-07-31T11:56:41.410 回答