Abnormal use
Regardless of whether it is the network or publishing, there are relatively few information about C# abnormality, and there are few developers in the field of industrial control in my industrial control field. Different is actually a very good mechanism and is worth promoting. To this end, I write this article based on the accumulation of past learning and combined with some project experience.
1. Why should you use abnormalities
Before starting this article, let's take a look at the commonly used "report errors" methods:
- Method 1: Return the error code
shortcoming:
- Users have to judge the return value, resulting in an increase in "circle complexity";
- If the method needs to be returned, the return content has to be passed through the "out" parameter.
The following is a pseudo -code. We can see that there are many inconvenience to use the error code:
Client client = new client ();
if (() == 1)
{{
if String Content == 1)
{{
// Execute other actions
}
}
class client
{{
Public int Connect ()
{{
// Execute other actions
If (SuccessEded)
{{
// Successful execution, return 1
Return 1;
}
else
{{
// The execution fails, and the error code is returned
Return errorCode;
}
}
Public int Receive (out String Result)
{{
If (SuccessEded)
{{
result = result;
Return 1;
}
else
{{
result = null;
Return errorCode;
}
}
}
- Method 2: Elementary information of global attribute records
shortcoming:
- You need to judge global attributes, users can easily miss;
- It will also increase the "circle complexity".
Client value = new client ();
();
if (== 1)
{{
string content = ();
if (== 1)
{{
// Execute other actions
}
}
class client
{{
public int errorCode {get; private set;}
public void connect ()
{{
// Execute other actions
If (SuccessEded)
{{
// Successful execution, the global attribute is set to 1
ErrorCode = 1;
Return;
}
else
{{
// The execution failed, set the error code
ErrorCode = errorcode;
Return;
}
}
Public String Receive ()
{{
If (SuccessEded)
{{
ErrorCode = 1;
Return result;
}
else
{{
ErrorCode = errorcode;
Return null;
}
}
}
The above two mechanisms are not only cumbersome, but the return error code cannot be used in some scenarios where there is no return value:
- Constructed function execution fails
- Set the attribute value execution failure
And abnormalities can make up for these defects.
Info
The book "Framework Design Guide" has explained in detail the benefits of abnormal abnormalities.
Abnormal combination with object -oriented language is precise. In terms of constructor, computing weight load, and attributes, developers cannot choose to return the value. For this reason, for object -oriented frameworks, error reports based on the return value cannot be standardized.
The abnormality promotes the consistency of the API because they are only designed for error reports. In contrast, there are many uses for returning values, and the error report is just one of the subsets. For this reason, although abnormalities can be restricted in specific modes, APIs that report errors by returning value reports are likely to use a large number of modes. Win32 API is a typical example of this inconsistent: it uses BOOL, Hresults, and GetLasterror.
In an error report based on the return value, the error processing code is always placed near the fault point. However, for abnormal processing, the developers of the application can have their own choices. They can capture abnormalities near the fault point, or they can concentrate the error processing code on the call stack.
Error processing code is easier to be localized. If the code reported by the return value is very strong, it often means that there is an IF statement in almost every functional code. These IF statements are used to deal with failure. With an abnormal error report, you can usually write a strong code in this way: multiple methods or operations are performed in order, and then you can handle errors according to the group behind the TRY syntax block, and you can even deal with higher levels at a higher level of the stack.
The error code is easy to be ignored, and in most cases.
The rich information that is abnormal can describe the cause of the error.
Anomaly is allowed to face non -processed anomalous processors.
The "processor that is not treated" here refers to
、
Support abnormal treatment incidents that subscribe to global.
The development of abnormal promotion tools. Abnormality is a model that defines a clear method. Because of this, tools, analyzers, performance counter and other tools may pay close attention to abnormalities.
2. Example of abnormal use
The pseudo code in the previous section was changed to use abnormalities as follows:
try
{{
Client value = new client ();
();
string content = ();
}
catch (Exception EX)
{{
();
}
class client
{{
public void connect ()
{{
// Execute other actions
If (SuccessEded)
{{
Return;
}
else
{{
// Execution failure, throw abnormal
Throw New InvalidOperationException ("Because ..., the connection fails.");
}
}
Public String Receive ()
{{
If (SuccessEded)
{{
Return result;
}
else
{{
Throw New InvalidOperationException ("Because ..., the data fails.");
}
}
}
Earlier, we also mentioned that the return error code cannot be used in the scene without return value. The following is a simple example of using abnormal use in the constructing function and property setter:
class client
{{
Public BOOL Isconnect {get; Private Set;}
Private String_Hostname;
Private int _Port;
// Through abnormal restrictions of hostname and port, they can only be modified without connecting.
public string hostname
{{
get => _hostname;
set
{{
if (iSconnect)
{{
Throw New InvalidoperationException ("The client is in a connected state and cannot modify the host name."););
}
_hostname = value;
}
}
public int port
{{
get => _Port;
set
{{
if (iSconnect)
{{
Throw New InvalidOperationException ("The client is in a connection state and cannot modify the port."););
}
_Port = value;
}
}
Public Client (String Hostname, Int Port)
{{
if (hostname))
{{
Throw new argumentexception ("parameter invalid.", nameof (hostname);
}
Hostname = hostname;
Port = port;
}
public void connect ()
{{
Isconnected = true;
}
}
It can be seen that the error code is more neat and cleaned through abnormal feedback, and can pass the abnormalitiesMessage
Properties report error information.
3. Which exception should be thrown?
For abnormalities, simple use is not complicated. But there are many types of abnormalities, and developers often confuse which abnormalities should be thrown out. Abnormal and error -related, errors are generally divided into two categories:
-
Error
-
Error
Divided into two categories:
- Program error
- System failure
Error: Error caused by error calls, such as passing into the NULL parameter. Such errors should not be processed by the framework, but the call party code should be modified.
There are 3 commonly used abnormalities corresponding to such errors:
-
ArgumentException
:ArgumentNullException
HarmonyArgumentOutOfRangeException
The base class is used to indicate the parameter error -
ArgumentNullException
: The parameters are empty abnormalities. When the parameter of the transmission method is null, this exception should be thrown out -
ArgumentOutOfRangeException
: The parameter value exceeds the range of abnormal range. When the parameters of the passing method exceed the limited range, this exception should be thrown out
The following is a simple example:
class client
{{
Public Void Connect (String Hostname, Int Port)
{{
if (hostname))
{{
Throw new argumentexception ("parameter invalid.", nameof (hostname);
}
// Execute other operations
}
}
Execution error-program error: Error that can be treated in the program. likeNo corresponding files are thrown out
FileNotFoundException
Odx, we can create a new file and continue to run.
There are many abnormalities corresponding to such errors. The most commonly used abnormalities are:
-
InvalidOperationException
: When the object is in an incorrect state, throw this abnormality
The following is a simple example:
class client
{{
Public BOOL Isconnect {get; Private Set;}
public void connect ()
{{
if (iSconnect)
{{
Throw New InvalidOperationException ("The client has been connected.");
}
// Other operations
Isconnected = true;
}
}
Execution error-system failure: The execution error cannot be processed in the program. For exampleOutOfMemoryException
。
There are many abnormalities corresponding to such errors, but these abnormalities should not be thrown by developers, but CLR is responsible. For example:
-
OutOfMemoryException
: When the inner layer is allocated, the abnormalities are thrown. Only CLR can throw this abnormality
Info
For more abnormal categories, seeChapter 7 Abnormal -Hihaojie -Blog Park7.3 Use of standard abnormal types
4. Disdiotic capture
There are throws, naturally capture. Unusual capture is not complicated, but there are still many details to pay attention to. Here we have to clarify the abnormal capture through several questions. We assume the followingConnect()
Method,:
void Connect (String Hostname)
{{
if (hostname is null)
{{
Throw new argumentnullexception (nameof (hostname));
}
// Execute other operations
}
Let's mention it here:ArgumentException
BeArgumentNullException
HarmonyArgumentOutOfRangeException
Father.
- Question 1: As follows, which paragraph can be compiled?
// code 1
try
{{
Connect (null!);
}
catch (Argumentexception EX)
{{
("Capture Argumentexception");
}
catch (ArgumentNullexception EX)
{{
("Capture Argumentnullexception exception");
}
// code 2
try
{{
Connect (null!);
}
catch (ArgumentNullexception EX)
{{
("Exception exception");
}
catch (Argumentexception EX)
{{
("Capture Argumentexception");
}
// code 3
try
{{
Connect (null!);
}
catch (ArgumentNullexception EX)
{{
("Exception exception");
}
catch (Argumentexception EX)
{{
("Capture Argumentexception");
}
Catch (InvalidoperationException EX)
{{
("Capture InvalidoperationException");
}
- Question 2: Will the following code output "Capture Argumentexception abnormalities"?
try
{{
Connect (null!);
}
catch (Argumentexception EX)
{{
("Capture Argumentexception");
}
- Question 3: Which information will output the following code?
try
{{
Sentmessage ("Abnormal test.");
}
catch (Argumentexception EX)
{{
("Capture Argumentexception");
}
Void SentMessage (String Message)
{{
try
{{
Connect (null!);
}
Catch (ARGUMENTOUUTOFRANGEEPTION EX)
{{
("Capture the argumentoutOutoFRANGEEPTION exception");
}
}
Through the above problems, we can draw the following conclusions:
-
When the abnormalities to capture the relationship between the father and son, the sub -class is abnormal, and the parent class is abnormal, otherwise it will not be compiled;
-
Sub -class abnormalities can be captured by capturing parent class abnormalities;
Exception
As all abnormal bases, capture it can capture all abnormalities. -
Uncaying abnormalities will be thrown further up;
Correspondingly, there are these conventions for capturing exceptions (standards):
- The processing method of the same way can capture their common parent class;
Such as "using errors" abnormalities (ArgumentException
Three brothers), their processing methods are the same (the code should be modified by the caller), which can be directly capturedArgumentException
Dreatment of abnormalities.
There are similarOperationCanceledException
HarmonyTaskCanceledException
- Only capture the exception to know how to deal with;
For unknown abnormalities, it should be thrown up further and processed from the previous level.
The following code demonstrates the treatment of known abnormalitiesTimeoutException
, Ignoring unknown abnormalitiesArgumentNullException
try
{{
Connect (hostname);
}
Catch (Timeoutexception EX)
{{
("Connection timeout, try secondary connection");
Connect (hostname);
}
void Connect (String Hostname)
{{
if (hostname is null)
{{
Throw new argumentnullexception (nameof (hostname));
}
// Execute other operations
if (usedtime> (100))
{{
Throw New Timeoutexception ("The connection is more than 100s."););
}
}
5. Disposure of abnormal capture and throwing again
Sometimes when we capture abnormalities, we don't want to deal with it, but we want to record and throw it twice, or turn it to other abnormalities and throw it out. Let's compare the following three -paragraph code to see what is the difference between their secondary throwing:
Exception Holder = NULL;
try
{{
try
{{
Throw New Exception ("Primitive abnormal");
}
catch (Exception EX)
{{
();
Holder = EX;
Throw;
}
}
catch (Exception EX)
{{
();
();
(Holder == EX);
}
Exception Holder = NULL;
try
{{
try
{{
Throw New Exception ("Primitive abnormal");
}
catch (Exception EX)
{{
();
Holder = EX;
Throw ex;
}
}
catch (Exception EX)
{{
();
();
(ex == Holder);
}
Exception Holder = NULL;
try
{{
try
{{
Throw New Exception ("Primitive abnormal");
}
catch (Exception EX)
{{
();
Holder = EX;
Throw New Exception ("Throwing abnormalities", ex);
}
}
catch (Exception EX)
{{
();
();
(Holder == EX);
}
We can find the above code we can find:
- Use directly
throw
Throw it out:The attribute will retain the original stack information;
- use
throw ex
Plusal throwing: The abnormality of the second throw is the same as the original example, butThe storage stack information is updated to the position of the secondary throwing;
- use
throw new Exception()
Throwing the second time: the anomalies were packaged in the second time,、
Many members have changed.
We can adopt the corresponding secondary throwing method as needed, but generally follow the following standards:
- If you don't need to be abnormal in the second packaging, you should use it directly
throw
Throw it out; - If you need to be abnormal in secondary packaging, you should use it
throw new SomeException
Throw abnormalities in the secondary and put abnormal abnormalities into new abnormalities.
You may be confused about the phrase "and pass the abnormality into the new abnormality." Here we look at the base class abnormalitiesException
Four constructors:
public Exception();
public Exception(string message)
public Exception(string message, Exception innerException)
protected Exception(SerializationInfo info, StreamingContext context)
The third structure functionException(string message, Exception innerException)
Need oneException
Example, yes, this parameter is specifically used for second packaging abnormalities. When we need to pack the original abnormality as other abnormalities, we need to pass the original abnormal instance through this parameter. This parameter is also possible when the second packaging is passed in, but it is a standard approach, which is conducive to developers to trace anomalies. The following is a simple example:
try
{{
Throw New Timeoutexception ("execution timeout.");
}
catch (Exception EX)
{{
Throw New InvalidOperationException ("If the execution fails, check the hardware status.", ex);
}
6. Common abnormalities
Let's introduce common abnormalities and their usage scenarios.
6.1 Base class abnormalities
The following abnormalities are not clear due to the abnormal classification of expression, and the developer should not throw the following abnormalities:
-
Exception
: Base class abnormalities, it is all abnormal base classes. When we customize abnormalities, we need to derive from this class or its subclasses. -
ApplicationException
HarmonySystemException
: At the beginning of the design,SystemException
The derivative class is used to represent the abnormality of the CLR (or system) itself,ApplicationException
The derivative class is used to indicate non -CLR abnormalities (application abnormality). But many abnormal classes do not follow this model, such asTargetInvocationException
DeriveApplicationException
, But thrown by CLR. thereforeApplicationException
It has lost its original meaning.
When we are custom abnormal, we no longer recommend itApplicationException
、SystemException
For the base class.
6.2 Commonly used abnormalities
-
InvalidOperationException
: If the object is in an incorrect state, throw this exception.For example: read only
FileStream
Write data. -
ArgumentException
、ArgumentNullException
、ArgumentOutOfRangeException
: When the user passes the error parameter, throw it outArgumentException
Or its derived class, and set it upParamName
Properties. If possible, try to choose an abnormal type located at the end of the inheritance level. -
OperationCanceledException
、TaskCanceledException
: It means that the operation is canceled.TaskCanceledException
Used for asynchronous programming,OperationCanceledException
Can be used for any scene.It should be noted that it is manually thrown in the asynchronous method
TaskCanceledException
At the same time, you need to pass through its constructorCancellationToken
OtherwiseTask
OutStatus
The attribute will not be marked asCanceled
-
FormatException
: The input string in the text analysis method does not meet the requirements or the specified format. -
FileNotFoundException
: It means that the file is not found. -
InvalidCastException
: Indicate invalid type conversion, commonly in compulsory conversion and boxing.The following code will throw this exception:
object content = ; int value = (int)content;
-
NotSupportedException
: It means that the current member's function is not supported.by
ReadOnlyCollection<T>
For example, it does not supportAdd()
Method, but realized againIList<T>
Interface, so itAdd()
The method was thrown out of this exception. -
NotImplementedException
: It means that the current membership function has not yet been realized. -
TimeoutException
: Express the timeout. Due to historical reasons, the web communication timeout did not throw the exception. byWebRequest
For example, it will be thrown out by the communication timeoutWebException
Abnormal and abnormal instanceStatus
Attribute valueEap the value.
6.3 CLR abnormal
Such abnormalities are usually thrown by CLR, and developers should not use these abnormalities.
-
NullReferenceException
、IndexOutOfRangeException
、AccessViolationException
: It means that the code is defective, and the developer needs to adjust the code. -
*Exception
: This exception is thrown when the stack is overflow, which is common in infinite recursive. When the stack is overflowing, it is almost impossible to keep the custody code consistent. The abnormal CLR2.0 default will stop the program immediately. Developers should not capture this exception (yes, at this time, the program crash should be performed). -
OutOfMemoryException
: Memory allocation fails. This exception will be thrown.
7. How to customize abnormalities
In the previous section, we talked about many predefined abnormalities. When the predefined abnormalities could not meet our needs, we need to customize abnormalities.
Customized abnormalities usually follow the following standards:
-
Customized abnormalities should be derived
Or other commonly used base class abnormalities;
-
The inheritance level should not be too deep;
-
Named using the "Exception suffix;
-
If multiple errors can be treated in one way, they should belong to the same type of abnormalities;
-
Customized abnormalities should have at least 4 constructors:
Public class someException: Exception, ISerializable {{ public someException (); Public someexcepiton (String Message); Public someexcepiton (String Message, Exception Inner); // The constructor required for serialization Protected someException (SerializationInfo Info, StreamingContext Context); }
Tips
Regarding custom abnormalities, binary serialization must be achieved (that is, implementation
SomeException(SerializationInfo info, StreamingContext context)
Construct function) No longer required in the new version .NET, andException(SerializationInfo info, StreamingContext context)
It is also marked for discarding ([Obsolete]
To. Therefore, the following example ignores the realization of binary serialization.
Now, we assume that there is such a hardware device:
- It is a ranging meter, and the computer communicates with it through TCP/IP (it is the server);
- When it is being measured, the measuring instructions are repeatedly sent to respond (that is, a communication timeout will occur);
- If the measurement distance exceeds returning, it will return the "Outofrange" string;
- If the measurement is successful, the value will return, indicating the measured distance.
Here we have to customize oneDeviceErrorException
It means all abnormalities when operating the hardware. Please think, how should the category of the ranginger be defined? How is this abnormal definition?
The following is a ranging class and correspondingDeviceErrorException
Abnormal, everyone can be used as a reference:
Class MeaSuerr
{{
Private tcpclient_client;
Public BOOL isconnect => _Client! = Null &&_Client.connect;
Private const string commit = "Measure";
Private Const String Outofrangresponse = "Outofrange";
Public Void Connect (String Hostname, Int Port)
{{
try
{{
_Client = New TCPClient (hostname, port);
}
Catch (Timeoutexception EX)
{{
Throw New DeviceErrorexception ("connection timeout.", ex,);
}
}
public double measure ()
{{
try
{{
if (! isconnect)
{{
Throw New Deviceerrorexception
}
byte [] writeBuffer = (Command);
Stream stream = _Client.getstream ();
_Client.getstream (). Writebuffer, 0,);
byte [] readbuffer = new byte [100];
int count = (readbuffer, 0,);
string content = (readbuffer, 0, count);
if (content == OUTOFRANCESPONSE))
{{
Throw New Deviceerrorexception
}
If (Content, out Double Result))
{{
Return result;
}
Throw New DeviceErrorexception ($ "to change the data failure. The content obtained is: [{content}],);
}
Catch (Timeoutexception EX)
{{
Throw New Deviceerrorexception ("Communication timeout.", ex,);
}
catch (deviceerrorexception)
{{
Throw;
}
catch (Exception EX)
{{
Throw New Deviceerrorexception
}
}
}
class deviceerrorexception: InvalidOperationException
{{
public deviceState State {get;}
public deviceerrorexception (): this (): this ()
{}
Public DeviceRrorexception (DeviceState State)
{{
State = state;
}
Public DeviceErrolXception (String Message): This (MESSAGE,)
{}
Public DeviceRrorexception (String Message, DeviceState State): Base (Message)
{{
State = state;
}
Public DeviceErReRorexception (String Message, Exception Innexception): this (Message, Innexception,), incexception,),),),),),),)
{}
Public DeviceRorexception (String Message, Exception Incexception, DevicesState State): Base (MESSAGE, Incexception)
{{
State = state;
}
}
enum deviceState
{{
Unknown,
DataParseerror,
Notconnected,
Timeout,
OutoFRANGE,
}
8. Abnormal and performance
Some developers are unwilling to use abnormalities to use abnormalities: affecting performance (personal decision is a bit nonsense, at least in the field of industrial control, I think this performance loss is completely unnecessary).
The "Framework Design Guide" mentioned that when the frequency of abnormal abnormality is higher than 100 per second, it is likely to bring significant performance effects. At this time, we can use the "Tester-Executive Mode" or "TRY mode", which are very common in .NET.
8.1 Tester-Executive Mode:
We take the collection as an example. We don't know the following codenumbers
Whether it is a collection of collection, so it may throw it outNotSupportException
:
ICollection<int> numbers = ...
(1);
ICollection<T>
Just definedIsReadOnly
Attributes, we can first determine whether the set is read only, and then perform ADD operation:
ICollection<int> numbers = ...
...
if (!)
{
(1);
}
in,IsReadOnly
Is a "tester",Add()
The method is "executor".
In "7. How to customize abnormalities", I defineMeasurer
The class also addedIsConnected
Attributes, to inform whether the hardware has been connected, this is also a "tester-executor mode".
Notice
"Competitive conditions" may appear in multi -threaded mode, and pay more attention when used.
8.2 TRY mode
The use of TRY mode is more common, such as()
、Dictionary<TKey, TValue>.TryGetValu()
Wait.
byDateTime
Try mode as an example, the general form is as follows:
public struct DateTime
{
public static DateTime Parse(string dateTime) { ... }
public static DateTime TryParse(string dateTime, out DateTime Result) { ... }
}
There are many details to pay attention to the TRY mode:
-
If members may throw abnormalities in common code, they should use the TRY-PARSE mode to avoid performance problems caused by abnormalities.
-
The TRY-PARSE mode should use the "TRY" prefix and use BOOL as the return type.
-
TRY method return
false
There is only one reason, and the remaining categories of failure should be thrown abnormal. -
To provide the TRY method with an equivalent method.
like
()
Equivalence()
-
Back the value of the TRY method through the OUT parameters.
-
When the TRY method returns FALSE, the default (t) is assigned to the OUT parameters.
-
Avoid writing data to the out parameter of the TRY method when throwing abnormality.
9. How to deal with the abnormality of "I don't know how to deal with it"
What should I do when the interface you call is thrown out of the unknown abnormality? The answer may be unexpected by most people: Do not capture it and let the program collapse is the best solution. There is such a paragraph in the "Framework Design Guide":
Your application should only deal with the abnormalities it understands. Generally speaking, after the problem of "something", it is almost impossible to restore the application from a state that may have been destroyed to normal. At this time, you only need to deal with the abnormalities that your application can respond reasonably. For all other abnormalities, no need to deal with, the operating system can suspend your application.
If you think that the current application is already ill and it should not continue to run, it is recommended to call()
Methods to stop the process, not abnormal. This method accepts a string parameter, we can pass the error message through this parameter. This error message will eventually be recorded by the operating system in "Computer Management → System Tools → Event Viewer → Windows Log → Application". The collapse of the procedure caused by unsealed abnormalities, the collapse information will also be recorded here.
Finally, according to the Windows log information, further check the cause of the collapse of the program and perform targeted repair.
()
The usage is as follows:
("An irreparable exception occurred", ex)
10. Moved abnormalities
Sometimes we caught abnormalities and do not want to deal with it directly, and we don't want to throw it out, but want to transfer it to other threads. Use a field/attribute to record this abnormality, and then throw it on the main thread? Not very suitable, this will destroy the original calling stack information.
.NET had been prepared for a long time, it provided itExceptionDispatchInfo
Class, specifically used to transfer abnormalities:
When transferring abnormality from other threads, or if the empty Throw statement that is not emptied after CATCH is thrown out again, it is necessary to use it again.ExceptionDispatchInfo
Class, it will continue to save the call stack in the process of reorganization. The following is a simple case:
Private ExceptiondispatchInfo_saveDexceptionInfo;
Private void backgroundworker () {
try {
Elastic
} Catch (Exception E) {{
_savedexceptionInfo = (E);
}
}
public object getresult () {
if (_done)
if (_SaveDexceptionInfo! = NULL) {
_savedexceptionInfo.throw ();
// The compiler cannot understand that this method is thrown out an exception, so an additional RETURN statement is needed.
Return null;
}
}
}
11. Filter abnormalities
Exception Filter is introduced in C#6. Through abnormal filter, we can repeatedly capture the same type of abnormalities:
catch (WebException ex) when ( == )
{ ... }
catch (WebException ex) when ( == )
{ ... }
The Boolean expression in WHEN clause can include side effects, such as calling a method to record the abnormal logs required for diagnosis.
It also has traps. Try analysis what will happen in the following code:
try
{{
throw new argumentexception ();
}
Catch (Argumentexception EX) when (==)
{{
("The first when the first when the clause" was hit ");
}
catch (argumentexception ex) when (is null) (is null)
{{
("Hit the Second WHEN clause");
}
The answer is: the "hit the second WHEN clause" will be output.
You might be confused: Shouldn't it throw an exception in the first WHEN sentence? After all, the Paramname attribute is not assigned, and it should be thrown when an equal judgmentNullReferenceException
Right. This is because the abnormality is captured by the CLR when it causes abnormality in the filter and the filter returns FALSE. The behavior cannot be separated from the filter and returned to FALSE, so it is difficult to debug. Pay more attention when using
12. Other matters
12.1 Do not modify the abnormal name and its father class at will
We mentioned earlier:
The processing method of the same way can capture their common parent class
This means that we should not modify custom abnormal base classes at will, otherwise the original abnormal processing code cannot work properly. Take the following code as an example, because the base class is abnormalInvalidOperationException
Change toException
, The original abnormal processing code no longer works:
//
// Class MyException: InvalidOperationException {}
// Modify the abnormality after the base class
Class MyException: Exception {}
// The abnormal processing code that can originally operates is invalidated
try
{{
Throw new myexception ();
}
Catch (InvalidoperationException EX)
{{
("Capture InvalidoperationException or its sub -class abnormalities");
}
12.2 The exception that will still be thrown up after capture:ThreadAbortException
It is obviously inseparable from the multi -threaded threadThread
。Thread
OutAbort()
Methods used to terminate the corresponding thread, and the terminate thread will throw it outThreadAbortException
Abnormal. However, the exception is more special, and it will continue to throw it up after the capture. Try the following code, what will happen:
Thread Thread = New Thread (Dosomething);
();
(100);
();
void dosomething ()
{{
try
{{
try
{{
While (true)
{{
(20);
}
}
Catch (Threadabortexception EX)
{{
("The first time to get Threadabortexception exception");
}
}
Catch (Threadabortexception EX)
{{
("The second capture to the Threadabortexception exception");
}
}
The answer is: it will output "the first time to the Threadabortexception exception" and "the second capture to the Threadabortexception exception". If you want to terminate the abnormality and throw it out further, you need to call()
Methods, it will bring thread status (ThreadState
)AbortRequested
Return toRunning
。
References:
- "Framework Design Guide: Construction, Construction, Customer and Mode of Construction of Reuse .NET Library"
- "C#7.0 Core Technology Guide"
Info
For some of the above two books, please refer to my reading notesReading Note Catalog Summary -Hihaojie -Blog Park