0

我正在尝试在运行时执行任务列表。我希望这是一个异步操作。每个任务都在调用 Web 服务并返回我添加到列表中的响应。完成所有操作后,我会将所有操作合并到一个文档中。

这是我的代码。目前它仅作为同步调用执行。我希望他们一次被枪杀。

List<XmlDocument> XmlResponse = new List<XmlDocument>();
XmlDocument xDocument = new XmlDocument();
ServiceRequest service = GetServiceRequest();
var tasks = new List<Task>();

Parallel.ForEach(service.IRN, x => 
{
    tasks.Add(Task.Factory.StartNew(() =>
    {
        XmlDocument xRequest = BuildServiceRequest(
            new ServiceRequest 
            {
                AccountNumber = service.AccountNumber, 
                MemberId = service.MemberId, 
                IRN = new List<string> { x }
            });
        Debug.Print("Service Call " + DateTime.Now.ToString("hh.mm.ss.ffffff"));
        XmlDocument xResponse = WebRequest.Submit(xRequest); // This is invoking service
        XmlResponse.Add(xResponse);
    }));
});

try
{
    Task.WaitAll(tasks.Where(x => x != null).ToArray());
    xDocument = PrepareServiceResponse();
    Debug.Print("Task Ends" + DateTime.Now.ToString("hh.mm.ss.ffffff"));
}

如果我现在运行此代码,则会同步调用该服务。任何人都可以建议在任务列表中一次拍摄所有电话的方法吗?

4

1 回答 1

3

您似乎在 Parallel ForEach 循环中创建了大量任务。您不需要这样做,因为 Parallel.ForEach 会为您处理任务的创建。

Parallel.ForEach(service.IRN, x => 
{
    XmlDocument xRequest = BuildServiceRequest(
       new ServiceRequest 
        {
            AccountNumber = service.AccountNumber, 
            MemberId = service.MemberId, 
            IRN = new List<string> { x }
        });
    Debug.Print("Service Call " + DateTime.Now.ToString("hh.mm.ss.ffffff"));
    XmlDocument xResponse = WebRequest.Submit(xRequest); 
    XmlResponse.Add(xResponse);
});

那应该这样做。进入下一行后,所有任务都将完成。但是,根据您进行的调用次数、使用的线程数以及每次调用需要多长时间,无法保证响应的顺序与 IRN 字符串的顺序相同。

顺便说一句,您可能会在添加到列表中时遇到错误。请参阅这两个问题以获得替代解决方案:我们可以使用 Parallel.ForEach() 将新元素添加到列表中吗?或者这种使用 Parallel.ForEach() 线程安全吗?

于 2013-10-23T12:39:42.333 回答