Skip to main content
 首页 » 编程设计

c#之并行 Webservice 循环跳过

2024年06月20日46TianFang

我正在使用并行循环来调用网络服务,因为单独的 for 循环太慢了。然而,结果跳过了一些项目。

代码:

private void readCSV(string FilePath, string Extension) 
{ 
    switch (Extension) 
    { 
        case ".csv": 
            var reader = new StreamReader(File.OpenRead(FilePath)); 
            int counter = 0; 
            List<int> phoneNo = new List<int>(); 
 
            while (!reader.EndOfStream) 
            { 
                var line = reader.ReadLine(); 
                phoneNo.Add(int.Parse(line)); 
            } 
            reader.Close(); 
 
            Parallel.For(0, phoneNo.Count, (index) => 
            { 
                counter++; 
                Literal1.Text += counter + " " + phoneNo[index] + " " + webserviceClass123.callWebserviceMethod(phoneNo[index]) + "<br/>"; 
            }); 
 
            break; 
    } 
} 

所以结果应该是(例子)

1 4189291 40.10 
2 5124910 23.10 
3 5123145 12.11 
... 
... 
50 4124919 20.58 

但结果是

3 8581892 41.10 
1 9281989 10.99 
50 4199289 02.22 

乱七八糟的,遗漏了很多数据

我如何让它井然有序并确保所有数据都得到体现?

请您参考如下方法:

您还不清楚您是否应该期望 Literal1.Text += ... 是线程安全的。我建议您使用Parallel.For 循环只是 来收集数据,然后再更改Literal1.Text。

例如,你可以这样写:

var results = new WhateverType[phoneNo.Count]; 
Parallel.For(0, phoneNo.Count, 
    index => results[index] = webserviceClass123.callWebserviceMethod(phoneNo[index])); 
 
var builder = new StringBuilder(); 
for (int i = 0; i < phoneNo.Count; i++) 
{ 
    builder.AppendFormat("{0} {1} {2}<br/>", 
        i, phoneNo[i], results[i]); 
} 
Literal1.Text = builder.ToString(); 

使用 Parallel LINQ 可能会更简洁:

var results = phoneNo 
    .AsParallel() 
    .Select(number => new {  
         number,  
         result = webserviceClass123.callWebserviceMethod(number) 
    }) 
    .AsOrdered() 
    .ToList() 
 
var builder = new StringBuilder(); 
foreach (int i = 0; i < results.Count; i++) 
{ 
    builder.AppendFormat("{0} {1} {2}<br/>", 
        i, result[i].number, results[i].result); 
} 
Literal1.Text = builder.ToString();