异步编程,为什么代码不会被执行

时间:2015-06-24 12:35:05

标签: c# multithreading asynchronous

我对异步编程很陌生,但我在应用程序中非常需要它。

我只是在控制台应用程序中尝试一些东西,但它似乎不起作用。我知道控制台应用程序不支持开箱即用的异步,因为WinForms应用程序中没有像UI线程这样的主线程。

无论如何,这就是我正在尝试的事情:

我有一个异步方法,它包含以下逻辑:

public static async Task MainAsync()
{
    Console.WriteLine("This method is being executed.");

    await Task.Delay(3000);

    Console.WriteLine("Async method has finished.");
}

现在,我想从我正在执行的控制台应用程序中执行此代码,以使其正常工作:

public static void Main(string[] args)
{
    Task t = MainAsync();
    t.Wait();
}

到目前为止没有问题,他们的应用程序按照预期执行。 首先写一个字符串,然后等待3秒,然后打印第二行,并以异步方式打印所有这些。

现在,我已经为我的代码创建了一个包装器,如下所示:

public static class AsynchronousContext 
{
    public static void Run(Task task)
    {
        task.Wait();
    }
}

所以,现在我的主要方法可以改为:

public static void Main(string[] args)
{
    AsynchronousContext.Run(MainAsync());
}

与上面的示例相同。

现在,我试图在我传递Run的{​​{1}}方法上创建一个重载。

Action

但是,当我将主方法调用更改为:

public static void Run(Action action)
{
    new TaskFactory().StartNew(action).Wait();
}

代码不再有效了。我得到第一行,而不是一行说明应用程序可以通过单击一个键完成,顺序说,主线程在等待之前完成。

我也尝试了以下内容,但我唯一想到的是没有内容的黑色控制台应用程序:

AsynchronousContext.Run(() => MainAsync());

任何能够尽可能简单地解释这里发生了什么的人?

1 个答案:

答案 0 :(得分:1)

MainAsync返回Task。您将此作为StartNew传递给Action,因此无法等待它完成。

此外,StartNew没有重载会接受返回Task的函数,因此StartNew无法等待它完成。

Task.Run通常更适合这种情况,假设您希望在线程池线程上运行您的工作。您可以在this blog post中阅读StartNew的陷阱。它有一个接受Func<Task>的重载:

public static void Run(Func<Task> createTask)
{
    Task.Run(createTask).Wait();
}

我认为这段代码只是为了证明原则,但是你通常不想调用Wait(),因为这会阻止。