Thread.Sleep在Task.Run中

Hal*_*ard 3 .net c# task-parallel-library async-await c#-5.0

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

这是我的一个测试

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

使用以下Terminator类:

public class Terminator
{
    public string IWillBeBack()
    {
        return "I will be back";
    }
}
Run Code Online (Sandbox Code Playgroud)

由此我预计结果很可能是之前,之后,然后我会回来.确实发生了这种情况.然后我对IWillBeBack方法进行了更改,使其能够休眠3秒钟.这个代码:

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

我预计结果仍然是之前,之后,然后再过 3秒后我会回来.这不是发生的事情.我反而得到之前之后,但从来没有我会回来的.

为什么是这样?

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

Jon*_*eet 7

您的测试在尝试打印"我将回来"之前完成.你没有做任何事情等到那个结束.根据测试运行器的不同,一旦测试结束,它的重定向Console.WriteLine可能已经断开.

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

[Test]
public void TaskRun()
{
    Console.WriteLine("Before");
    var task = Task.Run(() => Console.WriteLine(_terminator.IWillBeBack()));
    Console.WriteLine("After");
    task.Wait();
}
Run Code Online (Sandbox Code Playgroud)

  • @Halvard:请注意,您应该*仅*在示例控制台应用程序中使用`Wait`.作为一般规则,不要在生产系统中混合阻塞和异步代码.您可能想要阅读我的[`async`intro](http://nitoprograms.blogspot.com/2012/02/async-and-await.html)和[async`控制台程序的后续帖子](http:/ /nitoprograms.blogspot.com/2012/02/async-console-programs.html). (2认同)