考虑
string[] pages;
Task [] asyncOps =
(from url in urls select DownloadStringAsync(url)).ToArray();
try
{
pages = await Task.WhenAll(asyncOps);
...
}
catch(Exception exc)
{
foreach(Task<string> faulted in asyncOps.Where(t => t.IsFaulted))
{
… // work with faulted and faulted.Exception
}
}
来自https://msdn.microsoft.com/en-us/library/hh873173%28v=vs.110%29.aspx的。如何检索DID有效的页面?
或者更好的是,我如何继续计算其余页面?
答案 0 :(得分:4)
不是单独进行所有下载,然后单独处理每个成功/错误,我认为如果你定义一个单独的下载和处理错误,它会更清晰。操作:
Task [] asyncOps =
(from url in urls select DownloadStringWithErrorCheckingAsync(url)).ToArray();
string[] pages = await Task.WhenAll(asyncOps);
var successfulPages = pages.Where(x => x != null);
...
private static Task<string> DownloadStringWithErrorCheckingAsync(string url)
{
try
{
return await DownloadStringAsync(url);
}
catch(Exception exc)
{
... // work with exc
return null;
}
}
答案 1 :(得分:1)
我也有同样的问题。我需要启动几个任务,等待每个任务终止,然后处理所有任务Status / Exception / Result。
我不能使用斯蒂芬的解决方案,因为最终的处理并不是彼此独立的。它是某种形式:如果task1为Ok,我将尝试获取task2的结果,如果没有,我将获取task3结果。我需要每个回答来推断我的行为。
public static Task WhenAllNoThrow(this Task[] toWait, CancellationToken token)
{
return TaskEx.WhenAll(toWait).ContinueWith((t) => { t?.Exception?.Handle((exc) => true); }, token);
}
我不等待WhenAll的结果,而是ContinueWith的结果,其行为只能默默地处理异常。
它不是很优雅,但我们可以用这样的方法隐藏它:
[Inject] public InputController inputController { private get; set; }
[Inject] public ICommandFactory commandFactory { private get; set; }
[Inject] public NetworkMachineManager machineManager { private get; set; }
编辑:添加了空条件运算符?。
答案 2 :(得分:0)
不清楚是什么&#34; DownloadStringAsync&#34;是的,我以为它是WebClient.DownloadStringAsync
此函数不返回任务,您需要订阅complete事件以捕获结果。
它似乎不是你想要做的,所以我改变你的代码来做一个并行for循环。
Dictionary<string, string> pages = new Dictionary<string, string>();
Dictionary<string, string> errors = new Dictionary<string, string>();
string[] urls = new string[] { "http://www.google.com", "http://www.bbc.co.uk" };
Parallel.ForEach<string>(urls, (url) =>
{
var webClient = new System.Net.WebClient();
try
{
pages[url] = webClient.DownloadString(new Uri(url));
}
catch(Exception ex)
{
errors[url] = ex.Message;
}
});
// The successful
foreach(var kvp in pages)
{
Console.WriteLine(kvp.Key);
//Console.WriteLine(kvp.Value);
}
// The failures
foreach (var kvp in errors)
{
Console.WriteLine(kvp.Key);
//Console.WriteLine(kvp.Value);
}