try-catch(C# 参考)
https://msdn.microsoft.com/zh-cn/library/0yd65esw.aspx
Try-catch 语句包含一个后接一个或多个 catch 子句的 try 块,这些子句指定不同异常的处理程序。
引发异常时,公共语言运行时 (CLR) 查找处理此异常的 catch 语句。如果当前正在执行的方法不包含此类 catch 块,则 CLR 查看调用了当前方法的方法,并以此类推遍历调用堆栈。如果未找到任何 catch 块,则 CLR 向用户显示一条未处理的异常消息,并停止执行程序。
try 块包含可能导致异常的受保护的代码。将执行此块,直至引发异常或其成功完成。例如,强制转换 null 对象的以下尝试会引发 NullReferenceException 异常:
C#
object o2 = null;
try
{
int i2 = (int)o2; // Error
}
尽管可以不带参数使用 catch 子句来捕获任何类型的异常,但不推荐这种用法。一般情况下,只应捕获你知道如何从其恢复的异常。因此,应始终指定派生自 System.Exception 的对象参数,例如:
C#
catch (InvalidCastException e)
{
}
可以使用同一 try-catch 语句中的多个特定 catch 子句。在这种情况下,catch 子句的顺序很重要,因为 catch 子句是按顺序检查的。在使用更笼统的子句之前获取特定性更强的异常。如果捕获块的排序使得永不会达到之后的块,则编译器将产生错误。
筛选想要处理的异常的一种方式是使用 catch 参数。也可以使用谓词表达式进一步检查该异常以决定是否要对其进行处理。如果谓词表达式返回 false,则继续搜索处理程序。
C#
Catch (ArgumentException e) if (e.ParamName == “…”)
{
}
异常筛选器要优于捕获和重新引发(如下所述),因为筛选器将保留堆栈不受损坏。如果之后的处理程序转储堆栈,可以查看到异常的原始来源,而不只是重新引发它的最后一个位置。异常筛选器表达式的一个常见用途是日志记录。可以创建一个始终返回 false 并输出到日志的谓词函数,而且可以在异常通过时进行记录,无需处理并重新引发它们。
可在 catch 块中使用 throw 语句以重新引发已由 catch 语句捕获的异常。下面的示例从 IOException 异常提取源信息,然后向父方法引发异常。
C#
catch (FileNotFoundException e)
{
// FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
// Extract some information from this exception, and then
// throw it to the parent method.
if (e.Source != null)
Console.WriteLine("IOException source: {0}", e.Source);
throw;
}
你可以捕获一个异常而引发一个不同的异常。执行此操作时,请指定作为内部异常捕获的异常,如以下示例所示。
C#
catch (InvalidCastException e)
{
// Perform some action here, and then throw a new exception.
throw new YourCustomException("Put your error message here.", e);
}
当指定的条件为 true 时,你还可以重新引发异常,如以下示例所示。
C# catch (InvalidCastException e)
{
if (e.Data == null)
{
throw;
}
else
{
// Take some action.
}
}
从 try 块内,仅初始化在其中声明的变量。否则,在完成执行块之前,可能会出现异常。例如,在下面的代码示例中,变量 n 在 try 块内部初始化。尝试在 Write(n) 语句的 try 块外部使用此变量将生成编译器错误。
C#
static void Main()
{
int n;
try
{
// Do not initialize this variable here.
n = ;
}
catch
{
}
// Error: Use of unassigned local variable 'n'.
Console.Write(n);
}
=====
异步方法中的异常
异步方法由 async 修饰符标记,通常包含一个或多个 await 表达式或语句。await 表达式将 await 运算符应用于 Task 或 Task<TResult>。
当控件到达异步方法中的 await 时,将挂起方法中的进度,直到所等待的任务完成。任务完成后,可以在方法中恢复执行。
应用了 await 的完成任务可能由于返回此任务的方法中存在未处理的异常而处于错误状态。等待该任务引发异常。如果取消了返回任务的异步进程,此任务最后也可能为已取消状态。等待已取消的任务引发 OperationCanceledException。
若要捕获异常,请在 try 块中等待任务并在关联的 catch 块中捕获异常。
任务可能处于错误状态,因为等待的异步方法中发生了多个异常。例如,任务可能是对 Task.WhenAll 调用的结果。当等待此类任务时,仅捕捉到其中一个异常,而且你无法预测将会捕获到哪个异常。相关示例,请参见“示例”一节。
在下面的示例中,try 块包含对可能引发异常的 ProcessString 方法的调用。 catch 子句包含只在屏幕上显示一条消息的异常处理程序。当从 MyMethod 内部调用 throw 语句时,系统将查找 catch 语句并显示消息 Exception caught。
C#
class TryFinallyTest
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
} static void Main()
{
string s = null; // For demonstration purposes. try
{
ProcessString(s);
} catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at TryFinallyTest.Main() Exception caught.
* */
在下面的示例中,使用了两个 catch 块,并捕获到最先出现的最具体的异常。
若要捕获最不具体的异常,你可以将 ProcessString 中的 throw 语句替换为以下语句:throw new Exception()。
如果将最不具体的 catch 块置于示例中第一个,将显示以下错误消息:A previous catch clause already catches all exceptions of this or a super type ('System.Exception')。
C#
class ThrowTest3
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
} static void Main()
{
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (ArgumentNullException e)
{
Console.WriteLine("{0} First exception caught.", e);
}
// Least specific:
catch (Exception e)
{
Console.WriteLine("{0} Second exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/
下面的示例阐释异步方法的异常处理。若要捕获异步任务引发的异常,将 await 表达式置于 try 块中,并在 catch 块中捕获该异常。
将演示异常处理的示例中的 Throw New Exception 行取消注释。 任务的 IsFaulted 属性设置为 True,任务的 Exception.InnerException 属性设置为异常,并在 catch 块中捕获该异常。
取消注释 throw new OperationCancelledException 行以演示在取消异步进程时发生的情况。任务的 IsCanceled 属性设置为 true,并在 catch 块中捕获异常。在某些不适用于此示例的情况下,任务的 IsFaulted 属性设置为 true 且 IsCanceled 设置为 false。
C#
public async Task DoSomethingAsync()
{
Task<string> theTask = DelayAsync(); try
{
string result = await theTask;
Debug.WriteLine("Result: " + result);
}
catch (Exception ex)
{
Debug.WriteLine("Exception Message: " + ex.Message);
}
Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled);
Debug.WriteLine("Task IsFaulted: " + theTask.IsFaulted);
if (theTask.Exception != null)
{
Debug.WriteLine("Task Exception Message: "
+ theTask.Exception.Message);
Debug.WriteLine("Task Inner Exception Message: "
+ theTask.Exception.InnerException.Message);
}
} private async Task<string> DelayAsync()
{
await Task.Delay(); // Uncomment each of the following lines to
// demonstrate exception handling. //throw new OperationCanceledException("canceled");
//throw new Exception("Something happened.");
return "Done";
} // Output when no exception is thrown in the awaited method:
// Result: Done
// Task IsCanceled: False
// Task IsFaulted: False // Output when an Exception is thrown in the awaited method:
// Exception Message: Something happened.
// Task IsCanceled: False
// Task IsFaulted: True
// Task Exception Message: One or more errors occurred.
// Task Inner Exception Message: Something happened. // Output when a OperationCanceledException or TaskCanceledException
// is thrown in the awaited method:
// Exception Message: canceled
// Task IsCanceled: True
// Task IsFaulted: False
下面的示例阐释了在多个任务可能导致多个异常的情况中的异常处理。 try 块等待由 Task.WhenAll 的调用返回的任务。应用了 WhenAll 的三个任务完成后,该任务完成。
三个任务中的每一个都会导致异常。 catch 块循环访问异常,这些异常位于由 Task.WhenAll 返回的任务的 Exception.InnerExceptions 属性中。
C#
public async Task DoMultipleAsync()
{
Task theTask1 = ExcAsync(info: "First Task");
Task theTask2 = ExcAsync(info: "Second Task");
Task theTask3 = ExcAsync(info: "Third Task"); Task allTasks = Task.WhenAll(theTask1, theTask2, theTask3); try
{
await allTasks;
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.Message);
Debug.WriteLine("Task IsFaulted: " + allTasks.IsFaulted);
foreach (var inEx in allTasks.Exception.InnerExceptions)
{
Debug.WriteLine("Task Inner Exception: " + inEx.Message);
}
}
} private async Task ExcAsync(string info)
{
await Task.Delay(); throw new Exception("Error-" + info);
} // Output:
// Exception: Error-First Task
// Task IsFaulted: True
// Task Inner Exception: Error-First Task
// Task Inner Exception: Error-Second Task
// Task Inner Exception: Error-Third Task
try-catch(C# 参考)的更多相关文章
- SQL Server 致程序员(容易忽略的错误)
标签:SQL SERVER/MSSQL/DBA/T-SQL好习惯/数据库/需要注意的地方/程序员/容易犯的错误/遇到的问题 概述 因为每天需要审核程序员发布的SQL语句,所以收集了一些程序员的一些常见 ...
- android开发中遇到的bug
这种NullPointerException这么解决啊 Activity.dispatchTouchEvent 里try catch一下 参考:http://www.eoeandroid.com/th ...
- Android WifiDirect学习(一)
WiFi Direct基本介绍 Wi-Fi Direct标准允许无线网络中的设备无需通过无线路由器即可相互连接.与蓝牙技术类似,这种标准允许无线设备以点对点形式互连,不过在传输速度与传输距离方面则比蓝 ...
- SQL Server 容易忽略的错误
一.概述 因为每天需要审核程序员发布的SQL语句,所以收集了一些程序员的一些常见问题,还有一些平时收集的其它一些问题,这也是很多人容易忽视的问题,在以后收集到的问题会补充在文章末尾,欢迎关注,由于收集 ...
- 用weexplus从0到1写一个app
说明 基于wexplus开发app是来新公司才接触的,之前只是用过weex体验过写demo,当时就被用vue技术栈来开发app的开发体验惊艳到了,这个开发体验比react native要好很多,对于我 ...
- 转载SQL容易产生的错误问题
概述 因为每天需要审核程序员发布的SQL语句,所以收集了一些程序员的一些常见问题,还有一些平时收集的其它一些问题,这也是很多人容易忽视的问题,在以后收集到的问题会补充在文章末尾,欢迎关注,由于收集的问 ...
- js async/await
一.async 带async关键字的函数,是声明异步函数,返回值是promise对象,如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装. async f ...
- axios delete 请求
axios delete 请求 在传递一个参数的时候,直接把参数放在请求连接后面,用'/' 连接就可以了 this.axios.post(this.APIURL+'/'+ID) //http://ww ...
- SQLServer 异常捕获,回滚,再抛出
一个存储过程中多个更新操作,后面的更新操作出现异常,如果不手动回滚前面修改的数据是不会自动撤销的! BEGIN TRY BEGIN TRAN -- ..... COMMIT TRAN END TRY ...
- Vue + WebRTC 实现音视频直播(附自定义播放器样式)
1. 什么是WebRTC 1.1 WebRTC简介 WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频 ...
随机推荐
- 字符串与Objec之间互相转换
字符串与Objec之间互相转换可通过json实现. JSON.parse(str);// 字符串转Json Object JSON.stringify(obj);// Obj转字符串
- I/O多路复用 SELECT POLL -- 内核实现
等待队列 先补充个基础知识――等待队列 认识 定义 wait_queue_head_t wait_queue; 初始化 init_waitqueue_head(&wait_queue); 等待 ...
- 各种边缘检测算子特点比较(canny)
canny 最好.但是容易把噪点误判为边界.sobel prewitt log 效果差不多.prewitt比sobel 去噪效果好.roberts马马虎虎.适合什么图片那得看图片的噪点情况,一般can ...
- Maven引入本地jar包
<dependency> <groupId>${gorup}</groupId> <artifactId>${artifact}</artifac ...
- 安卓使用pull解析器解析XML文件
学习一下: public class MainActivity extends Activity { List<City> cityList; @Override protected vo ...
- Redis-收藏文章
http://www.cnblogs.com/capqueen/p/HowToUseRedis.html Redis到底该如何利用? http://www.cnblogs.com/yangecnu/ ...
- UDK:AdventureKit 攀爬系统
[目标] AdventureKit攀爬系统 [思路] [步骤] 1 拷贝 2 设置config,UDKGame\Config\DefaultEngine.ini 添加包 [UnrealEd.Edito ...
- WCF初探-5:WCF消息交换模式之双工通讯(Duplex)
双工通讯Duplex具有以下特点: 1它可以在处理完请求之后,通过请求客户端中的回调进行响应操作 2.消息交换过程中,服务端和客户端角色会发生调换 3.服务端处理完请求后,返回给客户端的不是reply ...
- apache认证、授权、访问控制
认证对象:某一个网站目录. 启用认证 1.即用AllowOverride指令指定哪些指令在针对单个目录的配置文件中有效:AllowOverride AuthConfig 2.设置密码登录访问某个站点或 ...
- [强连通分量] POJ 1236 Network of Schools
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16803 Accepted: 66 ...