In the project development, there are corresponding requirements for the stability and fault tolerance of the system and code. The difference between the code in the actual development project and the sample code is the comparison of the stability, fault tolerance and extensibility of the code running.
Because the core code for implementing functionality is the same for implementing a feature, it may just be optimized for writing, but it is most often the same for classes that implement an operation.
In this way, in the actual development process, we need to consider more issues, has not only been limited to a specific function implementation, more is the code stability and extensibility considerations.
The above is in the actual development needs to face the problem, the author in the recent blog, but also in consideration of how to write the exception, and how the exception needs to understand, in the blog, there are many friends of the unusual writing and processing put forward their own views, here I write some of their own understanding, May be written in a more superficial and sketchy, but only as a primer, you can lead the big boys to talk about their actual project experience. Hope to have a help, but also welcome people to put forward their own ideas and opinions, share their knowledge and insights.
I. Overview of dotnet anomalies
When it comes to exceptions, we need to know what is called an anomaly, and if we want to learn, we should know what we are going to learn, so there is a general understanding in the mind. An exception is an action that a member does not complete by declaring its name to be complete.
In. NET, constructors, get and set properties, add and delete events, call operator overloads, call conversion operators, and so on, have no way to return an error code, but in these constructs you need to report an error, and you must provide an exception handling mechanism.
In the handling of exceptions, the three blocks we often use are: try block; catch block; finally block. These three blocks can be used together, or can not write catch block use, exception handling blocks can be nested use, the specific method is described below.
In the exception handling mechanism, there are generally three options: to re-throw the same exception, the call stack to the higher layer of code to notify the occurrence of the exception, throw a different exception, want to call the stack layer of code to provide richer exception information; Let the thread exit from the bottom of the catch block.
There are some guiding suggestions for how exceptions are handled.
1. Proper use of the finally block
The finally block guarantees that any type of exception that is thrown by the pipeline can be executed, and the Finall block is generally used to clean up those operations that have been successfully started before returning the code after the caller or finally block.
2. Abnormal capture requires proper
Why is it appropriate to catch an exception? The following code, because we can not catch anything exception, after catching the exception, we need to deal with these exceptions, if we catch all the exceptions, but there is no foreseeable anomalies, 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 a "size-all" exception block, which should allow the exception to move up in the call stack, allowing the application code to handle the exception in a targeted manner.
In a catch block, you can use System.Exception to catch an exception, but it is best to re-throw the exception at the end of the catch block. The reasons are 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. Recovering from an exception
After catching the exception, we can write some code of abnormal recovery, so that the program can continue to run. When catching an exception, you need to catch a specific exception, fully grasp under what circumstances the exception will be thrown, and know which types derive from the type of exception caught. Do not handle or catch a System.Exception exception unless you re-throw the exception at the end of the catch block.
4. Maintenance status
In general, when we complete an operation or a method, we need to call several method combinations to complete, in the execution of the process will appear the previous methods to complete, the following method has an exception. When an unrecoverable exception occurs, the partially completed operation is rolled back because we need to recover the information, all of which we need to catch when catching the exception.
5. Hide implementation details to maintain the contract
Sometimes it may be necessary to catch an exception and re-throw a different exception, so that the contract of the method can be maintained, and the thrown heart exception type should be a specific exception. 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 inner exception throw new Namenotfoundexception () ; } catch (IOException e) { //throws a different exception, contains the exception information, and sets the original exception to the inner exception throw new Namenotfoundexception (); } finally { if (fs! = null) { fs.close (); } }
The above code is just a way of explaining a process. All exceptions thrown should be passed up the call stack of the method, rather than throwing a new exception after they were "swallowed". If a type constructor throws an exception and the exception is not captured in the type constructor method, the CLR captures the exception internally and throws a new typeinitialztionexception instead.
Two. Common handling mechanisms for dotnet anomalies
After the code has an exception, we need to handle the exception, and if an exception is not handled in a timely manner, the CLR terminates the process. In the handling of exceptions, we can catch exceptions in one thread and re-throw them in another thread. When an exception is thrown, the CLR looks up in the call stack for a catch block that matches the thrown exception type. If no catch block matches the thrown exception type, an unhandled exception occurs. The CLR detects that any thread in the process has a bit handling exception and terminates the process.
1. Exception Handling block
(1). Try block: The containing code usually needs to perform some common resource cleanup operations, or need to recover from an exception, or both. A 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 responds to an exception that needs to be executed. The expression in parentheses after the Catch keyword is the capture type. The capture type is specified from System.Exception or its derived class. The CLR searches for a matching catch block from top to bottom, so the specific exception should be taught on top. Once the CLR finds a catch block with a matching capture type, the code in all finally blocks of the inner layer is executed, and "inner finally" refers to all the finally blocks that start with the Tey block that throws the exception and to the catch block that matches the exception.
After catching an exception using System.Exception, you can re-throw the exception at the end of the catch block, because if we do not process or terminate the program in a timely manner after catching the exception exception, this exception may pose a significant security risk to the program, and the exception class is the base class for all exceptions and can Catch all the exceptions in the program, if there is a large exception, we do not timely processing, causing the problem is huge.
(3). Finally block: The code that contains is the code that guarantees execution. After all the code for the finally block finishes executing, the thread exits the finally block and executes the statement immediately after the finally block. If a finally block does not exist, the thread begins execution from the statement after the last catch block.
Note: The exception block can be combined and nested, for the three exception block sample, here do not introduce, the exception of the nesting can prevent the exception in the processing of the unhandled exception, these are not repeated.
2. Exception Handling Instances
(1). Exception Handling Extension method
<summary>///Format Exception message///</summary>//<param name= "E" > Exception object </param> <param name= "Ishidestacktrace" > whether to hide exception size information </param>//<returns> formatted exception information string </returns > 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 (String. Format ("{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
<summary>///check string is empty or empty and throws an exception////</summary>//<param name= "val" > Value Test < /param>//<param name= "paramname" > Parameter check name </param> public static void Checknullorempty (string Val, string paramname) {if (string. IsNullOrEmpty (Val)) throw new ArgumentNullException (paramname, "Value can ' t be null or empty"); }///<summary>///Please check that the parameters are not empty or empty and throw exceptions///</summary>//<param name= "param" &G t; Check value </param>//<param name= "paramname" > Parameter name </param> public static void Checknullparam (s Tring param, String paramname) {if (string. IsNullOrEmpty (param)) throw new ArgumentNullException (paramname, paramname + "can ' t be neither null nor EM Pty "); }///<summary>///Check the parameters are not invalid and throw an exception///</summary>//<param name= "param" > Check Values </param> <param name= "paramname" > Parameter name </param> public static void Checknullparam (object param, String p Aramname) {if (param = = null) throw new ArgumentNullException (paramname, paramname + "C An ' t is null "); }///<summary>///Please check that parameter 1 differs from parameter 2///</summary>//<param name= "param1" > value 1 measured Trial </param>///<param name= "Param1name" >name of value 1</param>//<param name= "param2" >value 2 to test</param>//<param name= "Param2name" >name of Vlaue 2</param> Public St atic void Checkdifferentsparams (Object param1, String Param1name, Object param2, String param2name) {if (param1 = = param2) {throw new ArgumentException (Param1name + "can ' t be the same as" + Param2name, param1 Name + "and" + param2name); }}///<summary>///Check that an integer value is positive (0 orlarger)///</summary>//<param name= "val" > Integer test </param> public static void Positiveva Lue (int val) {if (Val < 0) throw new ArgumentException ("The value must be greater tha n or equal to 0. ");
(3). Try-catch Extended Operation
<summary>///perform specified functions and subsequent functions on an object, and handle exceptions///</summary>//<typeparam name= "T" & GT; object type </typeparam>//<param name= "source" > Value </param>//<param Name= "Action" > The value to be Main function code of the line </param>//<param name= "failureaction" >catch function code </param>//<param name= "su Ccessaction "> function code executed after successful main function code </param>//<returns> main function code is executed successfully </returns> public static B Ool trycatch<t> (This T source, action<t> Action, action<exception> failureaction, action<t > successaction) where t:class {bool result; try {action (source); Successaction (source); result = true; } catch (Exception obj) {failureaction (obj); result = false; } return result; }//<summarY>///perform specified functions on an object and handle exceptions///</summary>//<typeparam name= "T" > Object type </typepara m>//<param name= "source" > Value </param>///<param Name= "action" > main function code to execute on the value </param> ; <param name= function code in "Failureaction" >catch </param>///<returns> main function code is executed successfully </returns> public static bool Trycatch<t> (this T source, action<t> Action, action<exception> failureaction) wher E T:class {return source. TryCatch (Action, failureaction, obj = {}); }///<summary>///execute specified function on an object and handle exception and return value////<typeparam NA Me= "T" > Object type </typeparam>//<typeparam name= "TResult" > Return value type </typeparam>//<param N Ame= "source" > Value </param>//<param Name= "func" > main function code to execute on value </param>///<param name= "f Ailurefunction code in Action >catch </param>//<param name= "successaction" > function code executed after successful main function code </param>// The return value of the <returns> function code that returns the default value of the object type </returns> public static TResult trycatch<t, if an exception occurs, tresult> (this T Source, Func<t, tresult> Func, action<exception> failureaction, action<t> 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; }///<summary>///execute specified function on an object and handle exception and return value////<typeparam NA Me= "T" > Object type </typeparam>//<typeparam name= "TResult" > Return value type </typeparam>//<param N Ame= "source" > Value </param>//<param Name= "func" > main function code to execute on the value </param>///<param name= "Failureaction" >c function code in Atch </param>////<returns> return value of function code, if an exception occurs, returns the default value of the object type </returns> public static Tresul T trycatch<t, tresult> (this t source, Func<t, tresult> Func, action<exception> failureaction) Where T:class {return source. TryCatch (func, failureaction, obj = {}); }
This article does not specifically introduce the use of try,catch,finally, but to give some more general methods, mainly the general developers of three blocks of the use of a knowledge, no longer do the repeated introduction.
The above is about. NET exception processing thought (above) the content, more related content please concern topic.alibabacloud.com (www.php.cn)!