解释两种调用异步操作的方法之间的区别

问题描述 投票:0回答:1

我有两种代码变体,将在下面提供。

代码的任务如下:我有两个 URL,我在这两个 URL 上发出 HTTP Get 请求,并且我想从那里获取内容。

在第一种情况中,我使用

Task.WhenAll
并传递两个异步方法调用,期望我的任务在不同线程中并行执行。 但从输出来看,都是在主线程中执行的,其id=1。

在第二种情况中,我使用await并期望我的任务按顺序但同时执行。 不过,await 的本质是等待操作执行而不阻塞主线程。

请解释我在哪里弄错了,哪种选项更适合这样的任务?

方法(两种情况相同)

public static async Task<string> FetchDataFromUrl(string url)
{
    await Console.Out.WriteLineAsync(Thread.CurrentThread.ManagedThreadId.ToString());
    try
    {
        using (HttpClient client = new HttpClient())
        {
            return await client.GetStringAsync(new Uri(url));
        }
    }
    catch (Exception ex)
    {
        await Console.Out.WriteLineAsync(ex.Message);
        throw;
    }
}

调用1号方法

string url1 = "https://jsonplaceholder.typicode.com/posts/1";
string url2 = "https://jsonplaceholder.typicode.com/comments/1";


var results = await Task.WhenAll(FetchDataFromUrl(url1), FetchDataFromUrl(url2));

调用2号方法

string url1 = "https://jsonplaceholder.typicode.com/posts/1";
string url2 = "https://jsonplaceholder.typicode.com/comments/1";

List<string> results = new List<string>
            {
                await FetchDataFromUrl(url1),
                await FetchDataFromUrl(url2),
            };
c# multithreading asynchronous async-await
1个回答
0
投票

在第一种情况下,我使用 Task.WhenAll 并传递两个异步方法 调用,期望我的任务以不同的方式并行执行 线程。但从输出来看,它们都是在 主线程,其 id = 1.

它们都是在主线程上启动的。这就是你所看到的。主线程启动它们,当它到达无法在不阻塞的情况下继续的点时,它返回要用作

Task.WhenAll
参数的任务。但是,当它在实际的 http 异步调用之前执行时,它们都会并行进行。

在第二种情况下,我使用await并期望我的任务执行 顺序但同时进行。虽然,await 的本质是 等待操作执行而不阻塞主程序 线程。

它们按顺序进行,但不是同时进行。 wait 的本质是在异步操作完成后为该方法的其余部分注册一个延续。如果操作已经完成,它就会继续工作,如果不是其他人完成工作。

© www.soinside.com 2019 - 2024. All rights reserved.