Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 结果有序的异步多个Web服务请求_C#_.net_Asynchronous_Async Await_Task Parallel Library - Fatal编程技术网

C# 结果有序的异步多个Web服务请求

C# 结果有序的异步多个Web服务请求,c#,.net,asynchronous,async-await,task-parallel-library,C#,.net,Asynchronous,Async Await,Task Parallel Library,给定一定数量的请求对象(最多9个),我需要异步调用相同次数的web服务端点。在.net4.0中,我们使用委托和IAsyncResult来实现这一点 使用asyc/await、TPL或两者结合使用.NET 4.6.1是否有更好的方法来实现这一点 将Parallel.ForEach与ConcurrentBag一起使用是否会如本文所建议的那样达到最佳效果 同步代码示例: public List<WbsResponse> GetWbsResults() { List<WbsRe

给定一定数量的请求对象(最多9个),我需要异步调用相同次数的web服务端点。在
.net4.0
中,我们使用
委托
IAsyncResult
来实现这一点

使用
asyc/await
TPL
或两者结合使用
.NET 4.6.1
是否有更好的方法来实现这一点

Parallel.ForEach
ConcurrentBag
一起使用是否会如本文所建议的那样达到最佳效果

同步代码示例:

public List<WbsResponse> GetWbsResults()
{
    List<WbsRequest> requests = CompileWbsRequests();
    List<WbsResponse> results = new List<WbsResponse>();
    foreach (var request in requests)
    {
        //Call same web service endpoint n number of times
        var response = CallWebService(request);
        results.Add(response);
    }

    //do something with results

    return results;
}

private WbsResponse CallWebService(WbsRequest request)
{
    //Call web service
}
编辑/更新2:根据线程,我对更新1做了一些更改:

await Task.Run(() => {
    Parallel.ForEach(requests, (request) => {
        var response = CallWebService(request);
        response.Order = request.Order;
        results.Add(response);
    });
});
需求概要:

  • 使用不同参数异步向同一端点发出多个web服务请求
  • 将web服务结果按与请求相同的顺序添加到列表中(就像它是同步的一样)

我认为您可以使用
Task.WaitAll
使代码以异步方式工作,并且看起来也会更漂亮:

public List<WbsResponse> GetWbsResults()
{
    List<WbsRequest> requests = CompileWbsRequests();
    var responses = await Task.WhenAll(requests.Select(CallWebService));
    return responses;
}
public List GetWbsResults()
{
列表请求=CompileWbsRequests();
var responses=wait Task.WhenAll(requests.Select(CallWebService));
回应;
}
但您必须按以下方式修改此方法才能返回任务:

private async Task<WbsResponse> CallWebService(WbsRequest request)
{
    //Call web service
}
专用异步任务CallWebService(WbsRequest请求)
{
//调用web服务
}

因为每个任务的完成时间不同,我认为您应该对请求进行编号,并按此编号排序响应

在请求中,初始化一个数字,并将该数字传递给相关响应。最后,当我得到结果时,我会订购它。 像这样:

    public async Task<List<WbsResponse>> GetWbsResults()
    {
        List<WbsRequest> requests = CompileWbsRequests();
        List<Task<WbsResponse>> tasks = new List<Task<WbsResponse>>();
        for (var i = 0; i < requests.Count; i++)
        {
            var task = new Task<WbsResponse>(() => { CallWebService(WbsRequest); });
            tasks.Add(task);
        }
        var responses = await Task.WhenAll(tasks);

        var responsesOrdered = responses.OrderBy(r => r.Order)

        //do something with results

        return results;
    }  



    public List<WbsRequest> CompileWbsRequests()
    {
        //create requests
        foreach(var request in requests)
        {
            request.Order += 1;
        }
    }


    private WbsResponse CallWebService(WbsRequest request)
    {
        //Call web service

        reponse.order = request.order;
        return reponse;
    }
public异步任务GetWbsResults()
{
列表请求=CompileWbsRequests();
列表任务=新列表();
对于(var i=0;i{CallWebService(WbsRequest);});
任务。添加(任务);
}
var responses=等待任务。WhenAll(任务);
var responseordered=responses.OrderBy(r=>r.Order)
//对结果做点什么
返回结果;
}  
公共列表CompileWbsRequests()
{
//创建请求
foreach(请求中的var请求)
{
请求。订单+=1;
}
}
专用WbsResponse CallWebService(WbsRequest请求)
{
//调用web服务
reponse.order=request.order;
返回响应;
}

这永远不会发生compile@SirRufo忘了更改另一个方法,现在我认为它已编译,甚至我没有尝试过它。这并不能确保结果的有序性,因为当所有的任务都在parallelNope中运行时,它仍然不会为响应@RajmondBurgaj编译Ethaks,但是如果它没有像Ulbo说的那样按顺序返回结果,这并不能解决我的问题。你不能不使用waitasync@SirRufo:谢谢你的评论。我更新了答案。我的C#编译器只接受
async void
async Task
async Task
-也许您有一个特殊的one@SirRufo不,你完全正确,它应该始终是异步的,因为我直接在StackOverflow上编写代码,没有编译器,只是知道如何工作。我错过了异步,这是我的错误:)
async List
将永远不会编译,但
async Task
将编译
    public async Task<List<WbsResponse>> GetWbsResults()
    {
        List<WbsRequest> requests = CompileWbsRequests();
        List<Task<WbsResponse>> tasks = new List<Task<WbsResponse>>();
        for (var i = 0; i < requests.Count; i++)
        {
            var task = new Task<WbsResponse>(() => { CallWebService(WbsRequest); });
            tasks.Add(task);
        }
        var responses = await Task.WhenAll(tasks);

        var responsesOrdered = responses.OrderBy(r => r.Order)

        //do something with results

        return results;
    }  



    public List<WbsRequest> CompileWbsRequests()
    {
        //create requests
        foreach(var request in requests)
        {
            request.Order += 1;
        }
    }


    private WbsResponse CallWebService(WbsRequest request)
    {
        //Call web service

        reponse.order = request.order;
        return reponse;
    }