Try...Catch....Finally

一、异步方法中的异常:

异步方法:异步方法有async来修饰,通常包含一个或多个await表达式,await表达式应用于Task或者Task<TResult>类型的操作, await表达式不能出现在catch块或finally块中。

1)当程序运行到async方法中的await表达式时,程序会挂起直到await完成。

1.await等待的任务发生未经处理的异常时,会抛出异常

2.await等待的任务被取消时,会抛出OperationCancaledException

想要捕捉这些异常,await表达式放于try块中,紧接着catch捕获。

 1         public  async Task DoSomethingAsync()
 2 
 3         {
 4 
 5             Task<string> theTask = DelayAsync();
 6 
 7             try
 8 
 9             {
10 
11                 string result = await theTask;
12 
13                 Console.WriteLine("Result: " + result);
14 
15             }
16 
17             catch (Exception ex)
18 
19             {
20 
21                 Console.WriteLine("Exception Message: " + ex.Message);
22 
23             }
24 
25             Console.WriteLine("Task IsCanceled: " + theTask.IsCanceled);
26 
27             Console.WriteLine("Task IsFaulted:  " + theTask.IsFaulted);
28 
29             if (theTask.Exception != null)
30 
31             {
32 
33                 Console.WriteLine("Task Exception Message: "
34 
35                     + theTask.Exception.Message);
36 
37                 Console.WriteLine("Task Inner Exception Message: "
38 
39                     + theTask.Exception.InnerException.Message);
40 
41             }
42 
43         }
44 
45         private  async Task<string> DelayAsync()
46 
47         {
48 
49             await Task.Delay(100);
50 
51  
52 
53             // Uncomment each of the following lines to
54 
55             // demonstrate exception handling.
56 
57  
58 
59             //throw new OperationCanceledException("canceled");
60 
61             //throw new Exception("Something happened.");
62 
63             return "Done";
64 
65         }

 

未经处理的异常抛出:

 

 任务被取消时抛出OperationCanceledException:

 

 

2)Task.WhenAll返回的异常: 

 1 public async Task DoMultipleAsync()
 2 
 3         {
 4 
 5             Task theTask1 = ExcAsync(info: "First Task");
 6 
 7             Task theTask2 = ExcAsync(info: "Second Task");
 8 
 9             Task theTask3 = ExcAsync(info: "Third Task");
10 
11  
12 
13             Task allTasks = Task.WhenAll(theTask1, theTask2, theTask3);
14 
15             try
16 
17             {
18 
19                 await allTasks;
20 
21             }
22 
23             catch (Exception ex)
24 
25             {
26 
27                 Console.WriteLine("Exception: " + ex.Message);
28 
29                 Console.WriteLine("Task IsFaulted: " + allTasks.IsFaulted);
30 
31                 foreach (var inEx in allTasks.Exception.InnerExceptions)
32 
33                 {
34 
35                     Console.WriteLine("Task Inner Exception: " + inEx.Message);
36 
37                 }
38 
39             }
40 
41         }
42 
43         private async Task ExcAsync(string info)
44 
45         {
46 
47             await Task.Delay(100);
48 
49             throw new Exception("Error-" + info);
50 
51         }


 

Catch块中通过Exception.InnerExceptions 迭代出每个任务的异常

 

 

二、.finally:通过finally块,我们可以释放try块中分配的任何资源,通常控制流离开try块后就进入finally,但是对于breakcontinuegotoreturn或者异常的向外传播会导致控制流的变化。

在经处理的异常里,finally块一定会执行,而在未经处理的异常里,它依赖于操作系统是否触发异常展开操作。通常未经处理的异常会导致应用程序的终结,这时finally块中的代码运行与否已经不重要了,若是一定要运行finally块中的代码,那么一种解决方案是加catch块捕捉异常,并在catch块中进行处理。另一种就是在调用含有try..finally块方法的方法中或者调用栈中的任何方法中进行捕捉,这样finally块就能得到调用。

 1 static  void Main(string[] args)
 2 
 3         {
 4 
 5             try
 6 
 7             {
 8 
 9                 // TryCast produces an unhandled exception.
10 
11                 TryCast();
12 
13             }
14 
15             catch (Exception ex)
16 
17             {
18 
19                 // Catch the exception that is unhandled in TryCast.
20 
21                 Console.WriteLine
22 
23                     ("Catching the {0} exception triggers the finally block.",
24 
25                     ex.GetType());
26 
27  
28 
29                 // Restore the original unhandled exception. You might not
30 
31                 // know what exception to expect, or how to handle it, so pass 
32 
33                 // it on.
34 
35                 throw;
36 
37             }
38 
39 public static void TryCast()
40 
41         {
42 
43             int i = 123;
44 
45             string s = "Some string";
46 
47             object obj = s;
48 
49             try
50 
51             {
52 
53                 // Invalid conversion; obj contains a string, not a numeric type.
54 
55                 i = (int)obj;
56 
57                 // The following statement is not run.
58 
59                 Console.WriteLine("WriteLine at the end of the try block.");
60 
61             }
62 
63             finally
64 
65             {
66 
67                 // Report that the finally block is run, and show that the value of
68 
69                 // i has not been changed.
70 
71                 Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i);
72 
73             }
74 
75         }

 

 

 

posted @ 2014-12-14 12:31  这是个坑  阅读(419)  评论(0)    收藏  举报