Below is the code I am using to retrieve data from several urls. For couple of urls I get exception but for all others I do get valid data. Problem is that with apporoach below, I am not able to collect data for threads that were able to retrieve data without any issue. Is there anyway to collect as much url response while also knowing which urls throw exceptions?
static void Main(string[] args)
{
var URLsToProcess = new List<string>
{
"http://www.microsoft.com",
"http://www.stackoverflow.com",
"http://www.google.com",
"http://www.apple.com",
"http://www.ebay.com",
"http://www.oracle.com",
"http://www.gmail.com",
"http://www.amazon.com",
"http://www.outlook.com",
"http://www.yahoo.com",
"http://www.amazon124.com",
"http://www.msn.com"
};
string[] tURLs = null;
try
{
tURLs = URLsToProcess
.AsParallel()
.WithDegreeOfParallelism(3)
.Select(uri => DownloadStringAsTask(new Uri(uri)).Result)
.ToArray();
}
catch (AggregateException ex)
{
AggregateException exf = ex.Flatten();
}
Console.WriteLine("download all done");
if (tURLs != null)
{
foreach (string t in tURLs)
{
Console.WriteLine(t);
}
}
}
static Task<string> DownloadStringAsTask(Uri address)
{
TaskCompletionSource<string> tcs =
new TaskCompletionSource<string>();
WebClient client = new WebClient();
client.DownloadStringCompleted += (sender, args) =>
{
if (args.Error != null)
tcs.SetException(args.Error);
else if (args.Cancelled)
tcs.SetCanceled();
else
tcs.SetResult(args.Result);
};
client.DownloadStringAsync(address);
return tcs.Task;
}
Yes, there is:
var tasks = URLsToProcess.Select(uri => DownloadStringAsTask(new Uri(uri))).ToArray();
while (tasks.Any())
{
try
{
Task.WaitAll(tasks);
break;
}
catch (Exception e)
{
// handle exception/report progress...
tasks = tasks.Where(t => t.Status != TaskStatus.Faulted).ToArray();
}
}
var results = tasks.Select(t => t.Result);
Use Task.WaitAll
to wait (synchronously since async-await
isn't available) for all the tasks concurrently to complete. If Task.WaitAll
completes successfully, break out of the while
loop and extract the results using Task.Result
. If there's an exception remove the faulted task and wait again for the other task and so forth.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.