问题
I'm quite new to async programming, but I need it badly inside on of our applications.
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();
}
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());
}
Which does the same as the sample above.
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?
回答1:
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.
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
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();
}
I assume this code is only to demonstrate the principles, however - you wouldn't ordinarily want to call Wait()
as this will block.
来源:https://stackoverflow.com/questions/31026737/async-programming-why-doesnt-the-code-get-executed