2014-12-30 35 views
0

下面是我用來從多個url檢索數據的代碼。對於幾個網址,我會得到例外,但對於其他所有其他網站我都會收到有效的數據。問題是,在下面的應用程序中,我無法收集能夠在沒有任何問題的情況下檢索數據的線程的數據。無論如何收集儘可能多的網址迴應,同時也知道哪些網址引發異常?在可能的情況下處理異常,同時獲取數據

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

回答

2

是的,有:

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

使用Task.WaitAll等待(同步,因爲async-await不可用)的同時所有的任務來完成。如果Task.WaitAll成功完成,跳出while循環並使用Task.Result提取結果。如果發生異常,請移除故障任務並再次等待其他任務等等。

+0

不知道我是否應該發佈一個新問題,但是您可以更改您的示例,以便我開始取得進展,哪些任務已完成,而其他任務仍在進行中,並且有些已引發異常? – BKS

+1

@johnsmith你應該發表一個不同的問題。你可以在這裏鏈接它,我會看看。 – i3arnon

+1

好的,會做到這一點。儘管感謝您的幫助。 – BKS

相關問題