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?
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();
See more on this question at Stackoverflow