Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of exception handling in .NET

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

Editor to share with you the example analysis of exception handling in .NET, I believe that most people do not know much about it, so share this article for your reference, I hope you will learn a lot after reading this article. Let's take a look at it!

1. Overview of Dotnet exceptions:

When it comes to anomalies, we need to know what anomalies are. If we want to learn everything, we should know what we want to learn, so that we can have a general understanding in mind. An exception means that a member fails to complete an action that its name claims to be capable of doing. In .NET, constructors, getting and setting properties, adding and deleting events, calling operator overloading, calling conversion operators, and so on, have no way to return error codes, but errors need to be reported in these constructions. then an exception handling mechanism must be provided.

In exception handling, we often use three blocks: try block; catch block; finally block. These three blocks can be used together or without writing catch blocks, and exception handling blocks can be nested. The specific methods will be described below.

In the exception handling mechanism, there are generally three options: re-throw the same exception and notify the code one layer higher of the call stack that the exception occurred; throw a different exception to provide richer exception information to the code higher than the call stack; and let the thread exit from the bottom of the catch block.

There are some instructive suggestions on how to handle exceptions.

1. Appropriate use of finally blocks:

The finally block ensures that no matter what type of exception the thread throws, the finall block is typically used to clean up operations that have been successfully started and then return to the caller or the code after the finally block.

two。 Exception catching should be appropriate:

Why catch exceptions properly? The following code, because we can not catch all exceptions, after catching exceptions, we need to deal with these exceptions, if we catch all the exceptions, but do not foresee the exceptions that will occur, we have no way to deal with these exceptions.

If the application code throws an exception, the other end of the application may expect to catch the exception, so it cannot be written as an "all-size-fits-all" exception block, but should be allowed to move up the call stack. Let the application code handle the exception specifically.

In catch blocks, you can use System.Exception to catch exceptions, but it is best to rethrow the exception at the end of the catch block. The reasons will be explained later.

Try {var hkml = GetRegistryKey (rootKey); var subkey = hkml.CreateSubKey (subKey); if (subkey! = null & & keyName! = string.Empty) subkey.SetValue (keyName, keyValue, RegistryValueKind.String);} catch (Exception ex) {Log4Helper.Error ("create registry error" + ex); throw new Exception (ex.Message,ex);}

3. To recover from an exception:

After we catch the exception, we can write some code for exception recovery so that the program can continue to run. When catching exceptions, you need to catch specific exceptions, fully understand when exceptions will be thrown, and know which types are derived from the types of exceptions caught. Do not handle or catch catch exceptions unless you re-throw the exception at the end of the System.Exception block.

4. Maintain the state:

In general, when we complete an operation or a method, we need to call the combination of several methods to complete. In the process of execution, there will be the completion of the first few methods and the exception of the latter methods. Rollback partially completed operations when an unrecoverable exception occurs, because we need to recover the information, so when we catch the exception, we need to capture all the exception information.

5. Hide the implementation details to maintain the contract:

Sometimes it may be necessary to catch an exception and rethrow a different exception so that the contract of the method can be maintained, and the heart exception thrown should be of a specific exception type. Look at the following code:

FileStream fs = null; try {fs = FileStream ();} catch (FileNotFoundException e) {/ / throws a different exception, contains the exception information, and sets the original exception to the internal exception throw new NameNotFoundException () } catch (IOException e) {/ / throws a different exception, including the exception information, and sets the original exception to the internal exception throw new NameNotFoundException ();} finally {if (fs! = null) {fs.close ();}}

The above code is just an illustration of how to handle it. You should let all thrown exceptions be passed up the method's call stack, rather than throwing a new exception after swallowing them. If a type constructor throws an exception that is not caught in the type constructor method, CLR catches the exception internally and throws a new TypeInitialztionException instead.

2. Common handling mechanisms for DotNet exceptions:

After an exception occurs in the code, we need to handle the exception. If an exception is not handled in a timely manner, CLR will terminate the process. In exception handling, we can catch the exception in one thread and rethrow the exception in another thread. When an exception is thrown, CLR looks up the call stack for a catch block that matches the type of exception thrown. If no catch blocks match the type of exception thrown, an unhandled exception occurs. CLR detects that any thread in the process has a bit handling exception and terminates the process.

1. Exception handling block:

(1) .try blocks: containing code usually requires some common resource cleanup operations, or recovery from exceptions, or both. The try block can also contain code that might throw an exception. A try block has at least one associated catch block or finall block.

(2) .catch block: contains code that needs to be executed in response to an exception. The expression in parentheses after the catch keyword is the capture type. The capture type is specified from System.Exception or its derived class. CLR searches for a matching catch block from top to bottom, so you should teach specific exceptions to be placed at the top. Once CLR finds a catch block with a match capture type, it executes the code in all the inner finally blocks. "inner finally" refers to all finally blocks from the tey block that throws the exception to the catch block that matches the exception.

After using System.Exception to catch exceptions, we can use to re-throw the exception at the end of the catch block, because if we do not handle or terminate the program in time after catching the Exception exception, this exception may cause great security risks to the program. Exception class is the base class of all exceptions and can catch all exceptions in the program. If there is a large exception, we do not deal with it in time, and the problem is huge.

(3) .finally block: contains code that is guaranteed to execute. After all the code of the finally block is executed, the thread exits the finally block and executes the statement immediately following the finally block. If no finally block exists, the thread starts execution from the statement after the last catch block.

Note: exception blocks can be combined and nested. I will not introduce the samples of three exception blocks here. Nesting of exceptions can prevent the recurrence of unhandled exceptions when handling exceptions. I will not repeat the above.

two。 Exception handling example:

(1)。 Exception handling extension method:

/ format exception message / exception object / whether to hide exception size information / formatted exception information string public static string FormatMessage (this Exception e, bool isHideStackTrace = false) {var sb = new StringBuilder (); var count = 0; var appString = string.Empty; while (e! = null) {if (count > 0) {appString + = "" } sb.AppendLine (string.Format ("{0} exception message: {1}", appString, e.Message)); sb.AppendLine ("{0} exception type: {1}", appString, e.GetType () .FullName); sb.AppendLine (string.Format ("{0} exception method: {1}", appString, (e.TargetSite = = null? Null: e.TargetSite.Name)); sb.AppendLine (string.Format ("{0} exception source: {1}", appString, e.Source); if (! isHideStackTrace & & e.StackTrace! = null) {sb.AppendLine (string.Format ("{0} exception stack: {1}", appString, e.StackTrace) } if (e.InnerException! = null) {sb.AppendLine (string.Format ("{0} internal exception:", appString)); count++;} e = e.InnerException;} return sb.ToString ();}

(2)。 Verify exception:

/ check that the string is empty or empty, and throw an exception / value test / Parameter check name public static void CheckNullOrEmpty (string val, string paramName) {if (string.IsNullOrEmpty (val)) throw new ArgumentNullException (paramName, "Value can't be null or empty") } / Please check that the parameter is not empty or empty, and throw an exception / check value / Parameter name public static void CheckNullParam (string param, string paramName) {if (string.IsNullOrEmpty (param)) throw new ArgumentNullException (paramName, paramName + "can't be neither null nor empty") } / check that the parameter is not invalid and throw an exception / check value / parameter name public static void CheckNullParam (object param, string paramName) {if (param = = null) throw new ArgumentNullException (paramName, paramName + "can't be null") } / Please check that parameter 1 is different from parameter 2 / value 1 Test / name of value 1 / / value 2 to test / name of vlaue 2 public static void CheckDifferentsParams (object param1, string param1Name, object param2, string param2Name) {if (param1 = = param2) {throw new ArgumentException (param1Name + "can't be the same as" + param2Name, param1Name + "and" + param2Name) }} / check that an integer value is positive (0 or greater) / integer test public static void PositiveValue (int val) {if (val)

< 0) throw new ArgumentException("The value must be greater than or equal to 0."); } (3).Try-Catch扩展操作: /// /// 对某对象执行指定功能与后续功能,并处理异常情况 /// /// 对象类型 /// 值 /// 要对值执行的主功能代码 /// catch中的功能代码 /// 主功能代码成功后执行的功能代码 /// 主功能代码是否顺利执行 public static bool TryCatch(this T source, Action action, Action failureAction, Action successAction) where T : class { bool result; try { action(source); successAction(source); result = true; } catch (Exception obj) { failureAction(obj); result = false; } return result; } /// /// 对某对象执行指定功能,并处理异常情况 /// /// 对象类型 /// 值 /// 要对值执行的主功能代码 /// catch中的功能代码 /// 主功能代码是否顺利执行 public static bool TryCatch(this T source, Action action, Action failureAction) where T : class { return source.TryCatch(action, failureAction, obj =>

{}) } / one performs a specified function on an object and handles the exception and return value / object type / / return value type / value / the main function code / the function code / the function code executed after the main function code in catch / main function code is successful, if an exception occurs Returns the default value of the object type public static TResult TryCatch (this T source, Func func, Action failureAction, Action successAction) where T: class {TResult result Try {var u = func (source); successAction (source); result = u;} catch (Exception obj) {failureAction (obj); result = default (TResult);} return result } / one performs the specified function on an object and handles the exception and the return value / object type / / return value type / / value / the return value of the function code / function code in the main function code / catch to be executed against the value, if an exception occurs The default value of the object type public static TResult TryCatch (this T source, Func func, Action failureAction) where T: class {return source.TryCatch (func, failureAction, obj = > {}) is returned. }

This article does not specifically introduce the use of try,catch,finally, but gives some general methods, mainly because the general developers have an understanding of the use of the three blocks, so they will not repeat the introduction.

3. Exception class analysis of Dotnet:

CLR allows any type of instance to be thrown by an exception. Here we introduce a System.Exception class:

1.Message attribute: indicates the reason why the exception was thrown.

[_ DynamicallyInvokable] public virtual string Message {[_ DynamicallyInvokable] get {if (this._message! = null) {return this._message;} if (this._className = = null) {this._className = this.GetClassName ();} return Environment.GetRuntimeResourceString ("Exception_WasThrown", new object [] {this._className});}}

As you can see from the above code, Message has only the get attribute, so message is read-only. GetClassName () gets the class of the exception. GetRuntimeResourceString () gets the runtime resource string.

The 2.StackTrace property: contains the names and signatures of all methods that were called before the exception was thrown.

Public static string StackTrace {[SecuritySafeCritical] get {new EnvironmentPermission (PermissionState.Unrestricted) .Demand (); return GetStackTrace (null, true);}}

EnvironmentPermission () is used to restrict the environment, PermissionState.Unrestricted sets the permission state, and GetStackTrace () gets the stack trace. Take a look at the code of GetStackTrace ().

Internal static string GetStackTrace (Exception e, bool needFileInfo) {StackTrace trace; if (e = null) {trace = new StackTrace (needFileInfo);} else {trace = new StackTrace (e, needFileInfo);} return trace.ToString (StackTrace.TraceFormat.Normal);} public StackTrace (Exception e, bool fNeedFileInfo) {if (e = = null) {throw new ArgumentNullException ("e");} this.m_iNumOfFrames = 0; this.m_iMethodsToSkip = 0; this.CaptureStackTrace (0, fNeedFileInfo, null, e);}

The above is the specific implementation of the get stack trace method, which is mainly when the user is debugging.

3.GetBaseException () gets the underlying exception information method.

[_ _ DynamicallyInvokable] public virtual Exception GetBaseException () {Exception innerException = this.InnerException; Exception exception2 = this; while (innerException! = null) {exception2 = innerException; innerException = innerException.InnerException;} return exception2;}

The InnerException property is an inherent exception, which is a virtual method that is overridden here. Take a look at the InnerException property in detail.

[_ DynamicallyInvokable] public Exception InnerException {[_ DynamicallyInvokable, TargetedPatchingOptOut ("Performance critical to inline this type of method across NGen image boundaries")] get {return this._innerException;}}

4.ToString () formats the exception information.

Private string ToString (bool needFileLineInfo, bool needMessage) {string className; string str = needMessage? This.Message: null; if ((str = = null) | (str.Length)

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report