在继续期间获取错误项目
本文关键字:取错误 项目 获取 继续 | 更新日期: 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
以获取响应字符串。