我对异步的以下上下文理解正确吗?

时间:2020-05-07 09:34:22

标签: c# asynchronous async-await console-application

我正在经历https://blog.stephencleary.com/2012/02/async-and-await.html,根据作者的说法,Context是以下其中之一:

  1. 如果您使用的是UI线程,则它是UI上下文。

  2. 如果您要响应一个ASP.NET请求,那么它就是一个ASP.NET请求上下文。

  3. 否则,通常是线程池上下文。

因此在具有以下代码的控制台应用程序中:

public static void Main()
{
    Thread.CurrentThread.Name = "MainThread";
    var task = SomeAsync();
    string result = task.Result;
    Console.WriteLine(result);
}

private static async Task<string> SomeAsync() {
    await Task.Delay(2000);
    return "random String";
}

在这里,我们从Main方法开始一个异步方法。这个异步方法的执行将花费2秒钟,到它完成时,控制将返回到Main方法中位于阻塞异步方法结果的行中。因此我们可以说MainThread被阻止,等待SomeAsync的结果。到SomeAsync完成时,MainThread仍被阻止。

所以我可以说async方法的延续将在与线程池不同的线程上执行(因为此代码有效并正确打印了字符串)?如果它是一个UI应用程序,则将导致死锁,但对于控制台应用程序则不会导致死锁。控制台应用程序是否是上下文无关的,并且在需要时可以使用线程池中的新线程?

1 个答案:

答案 0 :(得分:0)

我试图向您展示异步等待的工作原理:

class Program
{
    static void Main(string[] args)
    {
        TestAsync().Wait(); //This will run synchronously
    }

    private static async Task TestAsync()
    {
        Log("Test started");

        Log("Application will be blocked for 5 seconds");
        await Wait5Seconds();
        Log("Now it will run again");

        var task = Wait20Seconds();
        while (!task.IsCompleted)
        {
            Log("This will be logged during method execution cause we didn't await it");
        }

        var task1 = Wait20Seconds();
        Log("We will execute this log and then we will await the end of the execution of our task");
        await task1;

        Log("Test ended");
    }

    private static async Task Wait5Seconds()
    {
        await Task.Delay(1000 * 5);
    }

    private static async Task Wait20Seconds()
    {
        await Task.Delay(1000 * 20);
        Log("DONE!");
    }

    private static void Log(string message)
    {
        Console.WriteLine(string.Format("{0} - {1}", DateTime.Now, message));
    }
}