无法理解c#中async,await的行为

时间:2019-03-23 08:17:28

标签: c# async-await task

我正在学习c#的await异步功能。但是以下代码的行为使我感到困惑。

public static async Task CreateMultipleTasksAsync() {
    HttpClient client = new HttpClient() {
        MaxResponseContentBufferSize = 1000000
    };
    Task <int> download1 = ProcessUrlAsync("https://msdn.microsoft.com", client);
    Task <int> download2 = ProcessUrlAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client);
    int length1 = await download1;
    int length2 = await download2;
    Console.WriteLine("Sum is {0}", length1 + length2);
}

public static async Task <int> ProcessUrlAsync(string url, HttpClient client) {
    Console.WriteLine("I am here to process {0}", url);
    var byteArray = await client.GetByteArrayAsync(url);
    Console.WriteLine("processing is completed {0}", url);

    return byteArray.Length;
}

我期望的是在完成download1和download2之后,将执行CreateMultipleAsync()的最后一行,并且将打印长度总和。 问题是最后一行永远不会执行!

2 个答案:

答案 0 :(得分:2)

这是因为您在构造函数中使用了异步方法。从这里删除它。

此外,请勿使用async void。相反,您应该使用async Task

class MultipleAsync
{
    public async Task StartMultiple()
    {
        await CreateMultipleTasksAsync();

    }
    public static async Task CreateMultipleTasksAsync()
    {
        HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 };
        Task<int> download1 = ProcessUrlAsync("https://msdn.microsoft.com", client);
        Task<int> download2 = ProcessUrlAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client);
        int length1 = await download1;
        int length2 = await download2;
        Console.WriteLine("Sum is {0}", length1 + length2);
    }
    public static async Task<int> ProcessUrlAsync(string url, HttpClient client)
    {
        Console.WriteLine("I am here to process {0}", url);
        var byteArray = await client.GetByteArrayAsync(url);
        Console.WriteLine("processing is completed {0}", url);

        return byteArray.Length;

    }
}

用法:

MultipleAsync multipleAsync = new MultipleAsync();
await multipleAsync.StartMultiple();

由于第二个任务不取决于第一个任务的结果,因此可以并行运行两个任务。第二个任务将不等待第一个任务的完成:

HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 };
Task<int> download1 = ProcessUrlAsync("https://msdn.microsoft.com", client);
Task<int> download2 = ProcessUrlAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client);
var lengthts = await Task.WhenAll(download1, download2);
Console.WriteLine("Sum is {0}", lengthts.Sum());

答案 1 :(得分:2)

我认为问题在于您执行CreateMultipleTasksAsync()方法的方式。
如果您以这种方式通过同步方法执行操作

static void Main(string[] args)
    {
        CreateMultipleTasksAsync();
    }

然后您看不到最后一行的结果。
为什么?由于未等待此调用,因此Main方法将继续并结束,直到调用CreateMultipleTasksAsync()完成。所以看不到最后一行的结果。
通过这种方式执行,您会得到的

static void Main(string[] args)
    {
        var task = CreateMultipleTasksAsync();
        task.Wait();
    }

祝你好运。