在继续期间获取错误项目

本文关键字:取错误 项目 获取 继续 | 更新日期: 2023-09-27 18:35:38

我正在使用任务延续,如下面的代码所示。问题是我想知道哪些网址失败了。我希望有一些方法可以在持续代码中做到这一点,我正在检查 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;
}

在继续期间获取错误项目

如果你可以使用Bcl.Async包,我一定会推荐它。否则,启动所有任务,然后仅使用 Task.Factory.ContinueWhenAll 异步等待它们。

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

请注意,DownloadStringAsTask方法有一个变化,我用 URI 调用 TaskCompletionSource 构造函数,以便您可以通过AsyncState属性访问它。 textBox1只是一个要演示的文本框控件。您可以根据需要更改代码。

Task.Status将告诉您任务是被取消、出错还是成功完成。当任务成功完成(即task.Status == TaskStatus.RanToCompletion)时,您可以安全地访问task.Result以获取响应字符串。