C# 使代码在C中异步

C# 使代码在C中异步,c#,asynchronous,httprequest,task,C#,Asynchronous,Httprequest,Task,我有两种方法:第一种方法在一个地址上发送HTTP GET请求,第二种方法多次调用该地址,因此,它向多个IP发送请求。这两种方法都是异步的,因此它们不会在远程处理请求时阻止代码执行。问题是,由于我缺乏C语言知识,我不知道如何同时发送所有请求,而不是像我的代码那样一个接一个地发送。这是我的密码: public static async Task<string> SendRequest(Uri uri) { using (var client = new HttpClient())

我有两种方法:第一种方法在一个地址上发送HTTP GET请求,第二种方法多次调用该地址,因此,它向多个IP发送请求。这两种方法都是异步的,因此它们不会在远程处理请求时阻止代码执行。问题是,由于我缺乏C语言知识,我不知道如何同时发送所有请求,而不是像我的代码那样一个接一个地发送。这是我的密码:

public static async Task<string> SendRequest(Uri uri)
{
    using (var client = new HttpClient())
    {
        var resp = await client.GetStringAsync(uri).ConfigureAwait(false);
        return resp;
    }
}

public static async Task<string[]> SendToAllIps(string req)
{
    string[] resp = new string[_allIps.Length];

    for (int i = 0; i < _allIps.Length; i++)
    {
        resp[i] = await SendRequest(new Uri(_allIps[i] + req));
    }

    return resp;
}
如何使SendToAllIps在不等待上一个任务结果的情况下发送请求?此外,当所有请求完成时,SendToAllIps必须返回一个响应数组。据我所知,这是可以完成的,但在这种特殊情况下如何使用它?

您可以使用Task.whall来等待任务集合:

public static async Task<string[]> SendToAllIps(string req)
{
    var tasks = _allIps.Select(ip => SendRequest(new Uri(ip + req)));
    return await Task.WhenAll(tasks);
}
您可以使用Task.whall等待任务集合:

public static async Task<string[]> SendToAllIps(string req)
{
    var tasks = _allIps.Select(ip => SendRequest(new Uri(ip + req)));
    return await Task.WhenAll(tasks);
}
这里的关键是收集集合中的所有任务,然后使用wait等待它们。尽管我认为李的解决方案更优雅


这里的关键是收集集合中的所有任务,然后使用wait等待它们。尽管我认为Lee的解决方案更优雅…

以上提供的答案提供了正确的方法,但没有提供基本原理,让我解释一下代码的错误:

以下行创建了一个问题:

resp[i]=等待发送请求新Uri_allIps[i]+req

为什么?

当您在等待每个单独的请求时,它将停止对其余请求的处理,这是异步等待的行为,当您希望并发时,它几乎是对每个SendRequest的同步处理

决议: SendRequest作为异步方法返回为任务,您需要将其添加到IEnumerable中,然后您可以选择:

Task.WaitAll或Task.WhenAll

您的是Web API Rest应用程序,它需要一个同步上下文,因此您需要Task.whalll,它提供了一个任务作为结果以等待并将所有任务结果集成到一个数组中,如果您尝试使用Task.WaitAll,它将导致死锁,因为它无法搜索同步上下文,请检查以下内容:


您只能将Task.WaitAll用于控制台应用程序,而不是Web应用程序,控制台应用程序不需要任何同步上下文或UI线程上面提供的答案提供了正确的方法,但没有提供基本原理,让我解释一下您的代码有什么问题:

以下行创建了一个问题:

resp[i]=等待发送请求新Uri_allIps[i]+req

为什么?

当您在等待每个单独的请求时,它将停止对其余请求的处理,这是异步等待的行为,当您希望并发时,它几乎是对每个SendRequest的同步处理

决议: SendRequest作为异步方法返回为任务,您需要将其添加到IEnumerable中,然后您可以选择:

Task.WaitAll或Task.WhenAll

您的是Web API Rest应用程序,它需要一个同步上下文,因此您需要Task.whalll,它提供了一个任务作为结果以等待并将所有任务结果集成到一个数组中,如果您尝试使用Task.WaitAll,它将导致死锁,因为它无法搜索同步上下文,请检查以下内容:


您只能对控制台应用程序而不是Web应用程序使用Task.WaitAll,控制台应用程序不需要任何同步上下文或UI线程

此解决方案中哪个变量包含响应?wait Task.WhenAlltasks将返回字符串[],然而,正确的代码应该是return await Task.WhenAlltasks,或者您可以像var result=await Task.WhenAlltasks;返回结果谢谢。这样一个简单的结构,但工作完美!这是保证吗,Task.WhenAll以正确的顺序返回响应数组例如,响应[0]用于_allIps[0]?@JustLogin-是,请参阅for Task.WhenAll哪个变量在此解决方案中包含响应?wait Task.WhenAlltasks将返回字符串[],然而,正确的代码应该是return await Task.WhenAlltasks,或者您可以像var result=await Task.WhenAlltasks;返回结果谢谢。这样一个简单的结构,但工作完美!这是保证吗,Task.whalll以正确的顺序返回responses数组例如,response[0]是针对_allIps[0]?@JustLogin-是的,请参阅for Task的备注部分。如果您已经接受了正确的代码,我的代码是其工作的详细说明,我可以粘贴相同的详细信息,如果你真的在意你已经接受了正确的代码,我的是它工作的详细说明,如果你真的在意,我可以粘贴相同的细节