2014-12-30 2 views
0

아래 코드와 같이 작업 계속을 사용하고 있습니다. 문제는 어떤 URL이 실패했는지 알고 싶습니다. 나는 당신이 Bcl.Async 패키지를 사용할 수있는 경우에, 나는 확실히 그것을 추천 해드립니다 t.ISFaulted계속 중에 오류 항목 가져 오기

static void Main(string[] args) 
{ 
    var UIContext = TaskScheduler.FromCurrentSynchronizationContext(); 

    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; 
     Task task = Task.Factory.StartNew(() => 
     { 
      tURLs = URLsToProcess 
       .AsParallel() 
       .WithDegreeOfParallelism(3) 
       .Select(uri => DownloadStringAsTask(new Uri(uri)).Result) 
       .ToArray(); 
     }); 

     task.ContinueWith((t) => 
     { 
      if (t.IsFaulted) 
       // How to know which URL has failed 
     }, UIContext}); 

} 

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

죄송합니다. 내 대답을 삭제했습니다. 근본적으로 당신의 접근 방식에는 문제가 있습니다. 방금 작성한 코드가 매우 복잡하다는 것을 알았습니다. 해결책이라고 생각했던 것을 묻는 대신 달성하려는 것을 설명하십시오. 나는 도와 주겠다. –

+0

TPL을 사용하여 다양한 URL에서 데이터를 다운로드하고 있습니다. 일단 다운로드가 완료되면 어떤 URL이 실패하고 어떤 URL이 성공했는지 알고 싶습니다. 잘못된 것을 발견하면 제안 해주십시오. – BKS

답변

1

확인하고 contination 코드에서 그 일을 어떤 방법이 기대했다. 그렇지 않으면 모든 작업을 시작한 다음 Task.Factory.ContinueWhenAll을 사용하여 비동기 적으로 기다립니다. 당신이 AsyncState 속성을 통해 액세스 할 수 있도록 DownloadStringAsTask 방법의 하나의 변화가

private void DownloadData() 
{ 
    var uiContext = TaskScheduler.FromCurrentSynchronizationContext(); 
    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" 
     }; 

    var tasks = urLsToProcess.Select(x => DownloadStringAsTask(new Uri(x))) 
     .ToArray(); 

    Task.Factory.ContinueWhenAll(tasks, (Task<string>[] tasks1) => 
    { 
     foreach (var task in tasks1) 
     { 
      //task.AsyncState will contain the Uri, add it to the textbox 
      if (task.Status == TaskStatus.RanToCompletion) 
      { 
       textBox1.AppendText(string.Format("{0} : Completed", task.AsyncState)); 
      } 
      else if (task.Status == TaskStatus.Faulted) 
      { 
       textBox1.AppendText(string.Format("{0} : Faulted", task.AsyncState)); 
      } 
      else if (task.Status == TaskStatus.Canceled) 
      { 
       textBox1.AppendText(string.Format("{0} : Canceled", task.AsyncState)); 
      } 
      textBox1.AppendText(Environment.NewLine); 
     } 

    }, CancellationToken.None, TaskContinuationOptions.None, uiContext); 
} 

static Task<string> DownloadStringAsTask(Uri address) 
{ 
    TaskCompletionSource<string> tcs = 
     new TaskCompletionSource<string>(address); 
    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; 
} 

주, 나는 URI으로 TaskCompletionSource 생성자를 호출합니다. textBox1은 설명하기위한 TextBox 컨트롤입니다. 코드를 필요에 맞게 변경할 수 있습니다.

Task.Status은 작업 취소 또는 오류 발생 여부를 알려줍니다. 작업이 성공적으로 완료되면 (예 : task.Status == TaskStatus.RanToCompletion) 에 안전하게 액세스하여 응답 문자열을받을 수 있습니다.

+0

굉장하고, 매력처럼 일했습니다. – BKS