我对异步编程很陌生,但我在应用程序中非常需要它。
我只是在控制台应用程序中尝试一些东西,但它似乎不起作用。我知道控制台应用程序不支持开箱即用的异步,因为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());
任何能够尽可能简单地解释这里发生了什么的人?
答案 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()
,因为这会阻止。