[英]Async/Await exception handling
我的問題是基於文章異步編程最佳實踐
所以我有這個代碼
async static void AsyncVersion()
{
Stopwatch sw = Stopwatch.StartNew();
string url1 = "http://rsdn.ru";
string url2 = "http://gotdotnet.ru";
string url3 = "http://blogs.msdn.com";
var webRequest1 = WebRequest.Create(url1);
Console.WriteLine("Before webRequest1.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
...
所以這段代碼會引發異常,例如當我沒有inet連接時。 因此,當我遵循msdn的指導並將方法的簽名更改為Task(而不是void)時,但是在此之后,它吞噬了所有異常,但是嘿,外部catch
塊無法處理。
整個代碼如下
using System;
using System.Diagnostics;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication8
{
class Program
{
async static Task AsyncVersion()
{
Stopwatch sw = Stopwatch.StartNew();
string url1 = "http://rsdn.ru";
string url2 = "http://gotdotnet.ru";
string url3 = "http://blogs.msdn.com";
var webRequest1 = WebRequest.Create(url1);
Console.WriteLine("Before webRequest1.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
var webResponse1 = await webRequest1.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url1,
webResponse1.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);
var webRequest2 = WebRequest.Create(url2);
Console.WriteLine("Before webRequest2.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
var webResponse2 = await webRequest2.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url2,
webResponse2.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);
var webRequest3 = WebRequest.Create(url3);
Console.WriteLine("Before webRequest3.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
var webResponse3 = await webRequest3.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url3,
webResponse3.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);
}
static void Main(string[] args)
{
try
{
Console.WriteLine("Main thread id: {0}", Thread.CurrentThread.ManagedThreadId);
Task task = new Task(() => AsyncVersion());
task.Start();
Console.WriteLine("Right after AsyncVersion() method call");
//Ожидаем завершения асинхронной операции
task.Wait();
Console.WriteLine("Asyncronous task finished!");
}
catch (Exception e)
{
//Все исключения в TPL пробрасываются обернутые в AggregateException
Console.WriteLine("Exceptopn: {0}", e.Message);
}
Console.ReadLine();
}
}
}
舊版本:
using System;
using System.Diagnostics;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication8
{
class Program
{
async static void AsyncVersion()
{
Stopwatch sw = Stopwatch.StartNew();
string url1 = "http://rsdn.ru";
string url2 = "http://gotdotnet.ru";
string url3 = "http://blogs.msdn.com";
var webRequest1 = WebRequest.Create(url1);
Console.WriteLine("Before webRequest1.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
var webResponse1 = await webRequest1.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url1,
webResponse1.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);
var webRequest2 = WebRequest.Create(url2);
Console.WriteLine("Before webRequest2.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
var webResponse2 = await webRequest2.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url2,
webResponse2.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);
var webRequest3 = WebRequest.Create(url3);
Console.WriteLine("Before webRequest3.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
var webResponse3 = await webRequest3.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url3,
webResponse3.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);
}
static void Main(string[] args)
{
try
{
Console.WriteLine("Main thread id: {0}", Thread.CurrentThread.ManagedThreadId);
Task task = new Task(AsyncVersion);
task.Start();
Console.WriteLine("Right after AsyncVersion() method call");
//Ожидаем завершения асинхронной операции
task.Wait();
Console.WriteLine("Asyncronous task finished!");
}
catch (System.AggregateException e)
{
//Все исключения в TPL пробрасываются обернутые в AggregateException
Console.WriteLine("AggregateException: {0}", e.InnerException.Message);
}
Console.ReadLine();
}
}
}
new Task(() => AsyncVersion())
這是有問題的部分。 Task
構造函數不了解async
,因此它將忽略從AsyncVersion
返回的Task
。 (事實上,您必須使用lambda而不是直接編寫AsyncVersion
應該已經使您警惕發生了奇怪的事情。)
您有幾種解決方法(最后選擇最好):
也將Task<Task>
和Wait()
用於內部Task
:
Task<Task> task = new Task<Task>(AsyncVersion); task.Start(); task.Result.Wait();
使用Unwrap()
來改變Task<Task>
到Task
表示兩個Task
S:
Task<Task> task = new Task<Task>(AsyncVersion); task.Start(); task.Unwrap().Wait();
使用Task.Run()
,它確實了解async
:
Task task = Task.Run(() => AsyncVersion()); task.Wait();
根本不啟動Task
,只需調用async
方法:
Task task = AsyncVersion(); task.Wait();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.