找到你要的答案

Q:Parallel Webservice loop skipping

Q:平行的WebService环跳

I'm using a parallel loop to call a webservice because the individual for loop is too slow. However the results comes out skipping some of the item.

Code:

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;
    }
}

So the results should be like (example)

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

but it comes out as

3 8581892 41.10
1 9281989 10.99
50 4199289 02.22

It is jumbled up, and it misses a lot of data

How do I get it to be in order and ensure that all the data is represented?

我使用一个并行循环调用WebService因为环个人太慢。然而,结果出来跳过一些项目。

代码:

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

它是混乱的,它错过了很多数据

我如何使它是有序的,并确保所有的数据表示?

answer1: 回答1:

It's not at all clear that you should expect Literal1.Text += ... to be thread-safe. I would suggest you use the Parallel.For loop just to collect the data, and then change Literal1.Text afterwards.

For example, you could write:

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();

It would quite possibly be even cleaner to use 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();

一点都不清楚,你应该期望literal1文本+ =…线程安全。我建议你使用平行。循环来收集数据,然后更改literal1文本之后。

例如,你可以写:

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();

它很可能连清洁使用并行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();
c#  web-services