异步编程,为什么不执行代码 [英] Async programming, why doesn't the code get executed
问题描述
我对异步编程非常陌生,但是我非常需要在我们的应用程序内部使用它.
I'm quite new to async programming, but I need it badly inside on of our applications.
我只是在控制台应用程序中尝试某些操作,但似乎不起作用.我知道控制台应用程序不支持即开即用,因为WinForms应用程序中没有主线程,例如UI线程.
I'm just trying something inside a Console Application but it doesn't seem to work. I'm aware that a Console Application doesn't support async out of the box as there isn't a main thread like a UI thread in a WinForms Application.
无论如何,这是我正在尝试的方法:
Anyway, here's what I'm trying:
我有一个异步方法,其中包含以下逻辑:
I have an async method which contains the following logic:
public static async Task MainAsync()
{
Console.WriteLine("This method is being executed.");
await Task.Delay(3000);
Console.WriteLine("Async method has finished.");
}
现在,我想从我正在这样做的控制台应用程序中执行此代码,以使其正常工作:
Now, I want to execute this code from a Console Application which I'm doing like this, to make it work:
public static void Main(string[] args)
{
Task t = MainAsync();
t.Wait();
}
到目前为止,没有问题,它们的应用程序将按预期执行.首先写一个字符串,然后等待3秒钟,然后打印第二行,并以异步方式打印所有内容.
So far no problem, them application is executed as it's supposed to. First write a single string, then wait 3 seconds, then prints a second line, and all that in an async way.
现在,我为代码创建了一个包装,如下所示:
Now, I've created a wrapper around my code which looks like the following:
public static class AsynchronousContext
{
public static void Run(Task task)
{
task.Wait();
}
}
所以,现在我的主要方法可以更改为:
So, now my main method can be changed to:
public static void Main(string[] args)
{
AsynchronousContext.Run(MainAsync());
}
与上面的示例相同.
现在,我尝试在 Run
方法上创建一个重载,在该重载中我传递了一个 Action
.
Now, I've tried to create an overload on the Run
method in which I passes an Action
.
public static void Run(Action action)
{
new TaskFactory().StartNew(action).Wait();
}
但是,当我将主方法调用更改为:
However, when I change my main method call to:
AsynchronousContext.Run(() => MainAsync());
该代码不再起作用.我得到第一行,然后是一行,它说可以通过单击一个键(即依次单击主键,在等待之前完成主线程)来完成应用程序.
The code isn't working anymore. I get the first line and than a line that says that the application can be finished by clicking a key, in order words, the main thread finished before the await.
我也尝试了以下方法,但唯一想到的是我没有内容的黑色控制台应用程序:
I've tried the following also, but the only think I got was a black console application without contents:
public static void Run(Action action)
{
var task = new Task(action);
task.Wait();
}
任何人都可以尽可能简单地解释这里发生的事情吗?
Anyone who can explain as simple as possible what's happening here?
推荐答案
MainAsync
返回 Task
.您将它作为 Action
传递给 StartNew
,所以没有办法等待它完成.
MainAsync
returns a Task
. You are passing this to StartNew
as an Action
, so there is no way for it to wait for it to finish.
此外, StartNew
没有重载,该重载将接受返回 Task
的函数,因此 StartNew
无法等待使其完成.
In addition, there is no overload to StartNew
that would accept a function that returns a Task
, so StartNew
has no way of waiting for it to finish either.
Task.Run
通常更适合于此,假设您想在线程池线程上运行您的工作.您可以在此博客中阅读 StartNew
的陷阱发布.它有一个接受 Func< Task>
:
Task.Run
is generally better suited to this, presuming you want to run your work on a thread pool thread. You can read the pitfalls of StartNew
in this blog post. It has an overload that accepts a Func<Task>
:
public static void Run(Func<Task> createTask)
{
Task.Run(createTask).Wait();
}
我认为这段代码只是为了演示原理,但是-您通常不希望调用 Wait()
,因为这会阻塞.
I assume this code is only to demonstrate the principles, however - you wouldn't ordinarily want to call Wait()
as this will block.
这篇关于异步编程,为什么不执行代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!