-
重新包装任务失败时产生的多个异常(《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);//显示任务状态