Async programming, why doesn't the code get executed

情到浓时终转凉″ 提交于 2020-02-02 15:59:14

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!