<>1. It is certainly possible to catch exceptions in the synchronization method

<>2.Task Method internal try…catch Can catch exceptions

first , An exception occurred inside the thread , So the preferred processing method is to Task Used in try…catch… Handle exceptions

<>3.Task Method inner exception unhandled ( The anomaly disappeared into outer space .), How to snap externally

try…catch… Cannot capture directly Task Internal exception :
Write as follows , Unable to capture Task Internal exception .
try { var task = new Task(() => { throw new CustomException("task Internal error "); });
task.Start(); } catch(Exception e) { }
But we can call Task.Wait(), Result method ,ContinueWith catch Task Internal exception .

There are two methods to capture thread exceptions: blocking and asynchronous .
The blocking catch exception is : When one or more threads start , We've been waiting , Wait until all threads finish executing , Determine whether there are exceptions in these threads , Then execute the subsequent code .

The asynchronous catch exception is : After a thread starts , We won't wait for him to finish , You can directly execute other subsequent codes . When a thread has an exception , Will automatically return exception information , Or take the initiative to obtain thread exception information when necessary .

①Wait(),Result, GetAwaiter().GetResult() ( Blocking capture )

Task Exceptions thrown in can be caught , But it's not a direct capture , Instead, the Wait() Method or access Result Get exception when attribute , Priority to AggregateException Type throws an exception , without AggregateException For exception capture, the Exception Throw exception .
GetAwaiter().GetResult() Method with Exception Throw exception .

Test case 1:
#region adopt Wait Catch exception /// <summary> /// adopt wait Can capture Task Internal exception /// </summary> public
static void WaitException() { try {
// Different from thread ,Task Exceptions thrown in can be caught , But it's not a direct capture , Instead, the Wait() Method or access Result Attribute , Get exceptions from them , Wrap this exception as AggregateException type , Or directly Exception, Throw capture .
// By default ,Task Tasks are executed asynchronously by thread pool threads . You know Task Whether the task is completed , Can pass task.IsCompleted Attribute acquisition , You can also use task.Wait To wait Task complete .
Task t = Task.Run(() => TestException()); t.Wait(); } catch (Exception ex) { var
a= ex.Message; //a The value of is : One or more errors occurred . var b = ex.GetBaseException(); //b The value of is :Task Abnormal test
Console.WriteLine(a + "|*|" + b); } } static void TestException() { throw new
Exception("Task Abnormal test "); } #endregion
test result :

② But if no result is returned , Or do not want to call Wait() method , How to get exceptions ? use ContinueWith Catch exception ( Asynchronous capture )( recommend )

Test case 2:
#region adopt ContinueWith set up TaskContinuationOptions Parameters to catch exceptions ( recommend ) public static void
ContinueWithException(int x, int y) { Task<string> t = Task.Run<string>(() => {
Thread.Sleep(300); Console.WriteLine(" I am a thread still executing asynchronously "); return Sumt(x, y).ToString()
; }); //NotOnFaulted Indicates if there is no exception , Will be executed ContinueWith Internal code , But the thread will not block at this time //t.ContinueWith(r
=> //{ // string Exception = Convert.ToString(t.Exception); //
Console.WriteLine(" Abnormal information 1:" + Exception); //},
TaskContinuationOptions.NotOnFaulted); //Console.WriteLine(" Continue asynchronous execution 1");
//OnlyOnFaulted Indicates if there is an exception , Will be executed ContinueWith Internal code , But the thread will not be blocked at this time t.ContinueWith(r => {
//Thread.Sleep(3000); string Exception = Convert.ToString(t.Exception); Console.
WriteLine(" Abnormal information 2:" + Exception); }, TaskContinuationOptions.OnlyOnFaulted);
Console.WriteLine(" Continue asynchronous execution 2");
//askContinuationOptions.OnlyOnFaulted express : Specifies that the continuation task should only be scheduled if an unhandled exception is thrown by the task preceding the continuation task .
This option is not valid for multi task continuation .【 Namely : Only when an exception occurs, the exception information is recorded in the log 】 } private static int Sumt(int x, int y) {
return x / y; } #endregion
test result :

It is troublesome to use , Add an extension method :
AggregateException Catch all exceptions in multithreading .AggregateException Is a collection .
public static Task Catch(this Task task) { return task.ContinueWith<Task>(
delegate(Task t) { if (t != null && t.IsFaulted) { AggregateException exception
= t.Exception; Trace.TraceError("Catch exception thrown by Task: {0}", new
object[] { exception }); } return t; }).Unwrap(); } public static Task<T> Catch<
T>(this Task<T> task) { return task.ContinueWith<Task<T>>(delegate(Task<T> t) {
if (t != null && t.IsFaulted) { AggregateException exception = t.Exception;
Trace.TraceError("Catch<T> exception thrown by Task: {0}", new object[] {
exception}); } return t; }).Unwrap<T>(); }
③ Global capture Task Exceptions not observed in
TaskScheduler.UnobservedTaskException += (object sender,
UnobservedTaskExceptionEventArgs e)=> { Console.WriteLine(" Catch exception ,"+e.Exception.
InnerException.Message); };
Test case 3: Test cases 1 Medium t.Wait() Method comment out , See if it can be captured globally .
test result :
Figure I :

Figure II :

<>4. Catching exceptions in asynchronous methods

①async…await Can catch exceptions
try{   await task1; } catch{ }
②C# Asynchronous method , Try to avoid using async void Instead, use async Task

async void Any exceptions thrown by the SynchronizationContext( stay async void
Method is active when started ) Raised on , Unable to capture from async void Exception thrown by method . Which causes the program to crash .

The following code cannot be used Catch Capture from Async Void Method exception
private async void ThrowExceptionAsync() { throw new InvalidOperationException(
); } public void AsyncVoidExceptions_CannotBeCaughtByCatch() { try {
ThrowExceptionAsync(); } catch (Exception) { // The exception is never caught
here! throw; } }
Let's move on :
//Startup.cs public Startup() { Log("startup ctor"); LogBuffer.Clear();
LogBuffer.Push("other message"); } async void Log(string message) { await
LogBuffer.Push(message); }
If someone else references your library , He saw it Log The declaration of the function is as follows :

It's not easy to notice that this is an asynchronous method . For a C# programmer , It's easy to think of this as a normal function rather than async void,try catch No errors captured .

In order to solve the above problems , Can refer to youtube Method proposed by the previous developer , Use one SafeFireAndForget spread function .
//Startup.cs public Startup() { Log("startup ctor").SafeFireAndForget(); }
// Change to async Task async Task Log(string message) { await LogBuffer.Push(message);

Doing so allows you to use Log People who see this is an asynchronous method (Task), And in use Log It's easy to notice SafeFireAndForget
Then remind the user that this is a async Task .

async void Useful in a particular situation : Asynchronous event handler . Semantic differences make sense for asynchronous event handlers
. One approach I like to take is to minimize the code in asynchronous event handlers ( for example , Let it wait for the async Task
method ), Because if there is too much code and an exception is not caught, it will also cause the program to crash . The following code demonstrates this approach , This method uses async void
Method for event handlers without sacrificing testability :
private async void button1_Click(object sender, EventArgs e) { await
Button1ClickAsync(); } public async Task Button1ClickAsync() { // Do
asynchronous work. await Task.Delay(1000); }

©2019-2020 Toolsou All rights reserved,
Dynamic Simple registration login interface HTML+CSS+JQCSS Implement overflow display ellipsis 802.11 CCA and NAV mechanism Programmer refused due to low salary offer,HR become shame , Netizens instantly blew up ..abaqus Value of mass scaling factor _ABAQUS Mass scaling for Java Student information management system console version C Classic topics of language —— Insert a number into the sorted array Computer level 1 multi-point , How many points can I pass the computer test level 1 VINS-Fusion run kitti stereo and stereo+GPS data TS stay vue2 Writing in the project