-
重新包裝任務失敗時産生的多個異常(《C# in depth page. 424〉)
-
捕獲包含多個異常的AggregateException(《C# in depth page. 424〉)
-
以熟悉的方式處理異步異常
static async Task MainAsync()
{
Task<string> task = ReadFileAsync("garbge file");
try
{
string text = await task;//這裡使用await異常會從任務中解包,被catch到的就是IOException
Console.WriteLine("File contents: {0}", text);
}
catch (IOException e)
{
Console.WriteLine("Caught IOException: {0}", e.Message);
}
}
static void MainAsync()
{
Task<string> task = ReadFileAsync("garbge file");
try
{
task.Wait();//如果直接等待,則會抓到這個AggregateException
// Console.WriteLine("File contents: {0}", text);
}
catch (AggregateException e)
{
Console.WriteLine("Caught IOException: {0}", e.Message);
}
}
static async Task<string> ReadFileAsync(string filename)
{
Thread.Sleep(10 * 1000);
using (var reader = File.OpenText(filename))
{
return await reader.ReadToEndAsync(); //異步操作
}
}
static async Task MainAsync()
{
Task<int> task = ComputeLengthAsync(null);
Console.WriteLine("Fetched the task"); //這個會被執行到
try
{
int length = await task;//此時才能 Catch 到 ArgumentNullException
}
catch (ArgumentNullException ex)
{
}
// Console.WriteLine("Length: {0}", length);
}
static async Task<int> ComputeLengthAsync(string text)
{
if (text == null)
{
throw new ArgumentNullException("text");//雖然這個Exception很早就被抛出了,但是一直要到await那一句才會被catch到。
}
await Task.Delay(500);
return text.Length;
}
static async Task MainAsync()
{
Task<int> task = ComputeLengthAsync(null);
Console.WriteLine("Fetched the task");
int length = await task;
}
//以下方法本身不是一個異步方法,執行時使用的是正常的異步流
static Task<int> ComputeLengthAsync(string text)
{
if (text == null)
{
//将參數驗證與實作分離
throw new ArgumentNullException("text");
}
return ComputeLengthAsyncImp(text);
}
static async Task<int> ComputeLengthAsyncImp(string text)
{
await Task.Delay(10000);
return text.Length;
}
-
通過抛出OperationCanceledException來建立一個取消的任務
static async Task ThrowCancellationException()
{
throw new OperationCanceledException();
}
Task task = ThrowCancellationException();
Console.WriteLine(task.Status);//Canceled
-
通過一個取消的延遲操作來取消異步方法
static async Task DelayFor30Seconds(CancellationToken token)
{
Console.WriteLine("Waiting for 30 seconds...");
await Task.Delay(TimeSpan.FromSeconds(30), token);//啟動一個異步的延遲操作
}
CancellationTokenSource soucre = new CancellationTokenSource();
var task = DelayFor30Seconds(soucre.Token);//調用異步方法
soucre.CancelAfter(TimeSpan.FromSeconds(1));//請求延遲的token取消工作
Console.WriteLine("Initial status: {0}", task.Status);
try
{
task.Wait();//等待完成(同步)
}
catch (AggregateException e)
{
Console.WriteLine("Caught {0}", e.InnerExceptions[0]);
}
Console.WriteLine("Final status: {0}", task.Status);//顯示任務狀态