C #~ Asynchronous programming continues ~ W3wp.exe crash triggered by awaitand async- problem-friendly solution,

Source: Internet
Author: User

C #~ Asynchronous programming continues ~ W3wp.exe crash triggered by awaitand async- problem-friendly solution,
Reasons for deadlocks

The reason for understanding the damn lock is to understand how await processes contexts. By default, when an unfinished Task is await, the current context will re-obtain and continue executing the remaining code when the Task is completed. This context is the current SynchronizationContext, unless it is empty. SynchronizationContext of WEB applications is exclusive and only one thread is allowed to run. When await is finished, it tries to execute its remaining part in its original code context, but there is already a thread in the context of the Code, that is the thread that has been waiting for async to complete synchronization. The two of them are waiting for each other, so they are deadlocked.

Pay attention to the asynchronous usage of MSDN.
Rules
Description
Exceptions
Avoid using async void
Prioritize the use of async tasks instead of async void
Event handlers
Async to top
Do not mix blocking and async code
Console main method
Note that the context for execution is configured.
Set ConfigureAwait (false) whenever possible)
Except for those requiring context

 

Grateful heart

Thanks for sharing many articles on the Internet. In related articles, I found a non-blocking solution for using asynchronous code in synchronous code. I also wrote several test demos myself, however, the Asynchronous Method with return values such as Task <T> still has a deadlock. The previous Code is as follows:

/// <Summary> // uncle test /// </summary> public class tools {# region assume that these methods are encapsulated by a third party, the public static async Task TestAsync () {await Task. delay( 1000 ). configureAwait (false); // No Deadlock} public static async Task <string> GetStrAsync () {return await Task. run () => "OK "). configureAwait (false);} public static async Task DelayTestAsync () {Logger. loggerFactory. instance. logger_Info ("DelayAsync"); await Task. delay( 1000);} public static async Task <string> DelayGetStrAsync () {return await Task. run () => "OK") ;}# endregion # region we need to encapsulate it in our own code, solve the thread deadlock // <summary> // synchronously call an asynchronous entity without return values // </summary> // <param name = "func"> </ param> public static void ForWait (Func <Task> func) {func (). configureAwait (false );} /// <summary> /// an asynchronous object that has returned values synchronously called // </summary> /// <typeparam name = "T"> </typeparam>/ // <param name = "func"> </param> // <returns> </returns> public static T ForResult <T> (Func <Task <T> func) {var a = func ();. configureAwait (false); return. result ;}# endregion}

For the above Code, when executing a Task reverse return type (that is, there is no returned result), the program is no problem, but there can be returned results, the above ForResult method will still generate deadlocks! I certainly won't stop here. After finding some articles, I finally got the result and simplified the current context and asynchronous context.

After processing a ticket,Finally, synchronization and Asynchronization are achieved.,Therefore, people are the smartest animal. Everything is possible, as long as you think!

The Code of Lind. DDD. Utils. AsyncTaskManager is as follows, hoping to provide some inspiration and help.

 

/// <Summary> // asynchronous thread management-call asynchronous in a synchronization program, solved the thread deadlock issue. // </summary> public class AsyncTaskManager {// <summary> // run the Asynchronous Method without return type. /// </summary>/ // <param name = "task"> </param> public static void RunSync (Func <Task> task) {var oldContext = SynchronizationContext. current; // synchronous context var synch = new ExclusiveSynchronizationContext (); // asynchronous context SynchronizationContext. setSynchronizationContext (synch); // sets the current synchronization context sy Nch. post (async obj =>{ try {await task ();} catch (Exception e) {synch. innerException = e; throw;} finally {synch. endMessageLoop () ;}}, null); synch. beginMessageLoop (); SynchronizationContext. setSynchronizationContext (oldContext );} /// <summary> /// run the asynchronous method whose return type is T /// </summary> /// <typeparam name = "T"> </typeparam>/ // <param name = "task"> </param> // <returns> </returns> public static T RunSy Nc <T> (Func <Task <T> task) {var oldContext = SynchronizationContext. current; var synch = new ExclusiveSynchronizationContext (); SynchronizationContext. setSynchronizationContext (synch); T ret = default (T); // The default value of the action is synch. post (async obj =>{ try {ret = await task ();} catch (Exception e) {synch. innerException = e; throw;} finally {synch. endMessageLoop () ;}}, null); synch. beginMessageLoop (); Sync HronizationContext. setSynchronizationContext (oldContext); return ret ;}/// <summary> // asynchronous context object /// </summary> class ExclusiveSynchronizationContext: SynchronizationContext {private bool done; public Exception InnerException {get; set;} readonly AutoResetEvent workItemsWaiting = new AutoResetEvent (false); readonly Queue <Tuple <SendOrPostCallback, object> items = new Queue <Tuple <SendOrPostCal Lback, object >>(); public override void Send (SendOrPostCallback d, object state) {throw new NotSupportedException ("We cannot send to our same thread ");} /// <summary> /// add to asynchronous queue /// </summary> /// <param name = "d"> </param> /// <param name = "state"> </param> public override void Post (SendOrPostCallback d, object state) {lock (items) {items. enqueue (Tuple. create (d, state);} workItemsWaiting. set () ;} // <Summary> /// asynchronous end // </summary> public void EndMessageLoop () {Post (obj => done = true, null );} /// <summary> /// process messages in the asynchronous queue /// </summary> public void BeginMessageLoop () {while (! Done) {Tuple <SendOrPostCallback, object> task = null; lock (items) {if (items. count> 0) {task = items. dequeue () ;}} if (task! = Null) {task. Item1 (task. Item2); if (InnerException! = Null) // the method threw an exeption {throw new aggresponexception ("AsyncInline. run method threw an exception. ", InnerException) ;}} else {workItemsWaiting. waitOne () ;}} public override SynchronizationContext CreateCopy () {return this ;}}}

Finally, we are testing and we can see that there is no deadlock in the thread!

Uncle await & async article list

C #~ Asynchronous programming continues ~ W3wp.exe crash caused by awaitand async

C #~ Asynchronous programming continues ~ Parallel async asynchronous and synchronous Methods

The foundation is the top priority ~ The cost of multithreading ~ My memory has been eaten!

EF architecture ~ The path to EF asynchronous Transformation ~ Warehouse interface transformation ~ Continued

EF architecture ~ The path to EF asynchronous Transformation ~ Enable DbContextRepository to Implement Asynchronous Interfaces

EF architecture ~ The path to EF asynchronous Transformation ~ Warehouse interface Transformation

C #~ Asynchronous programming continued ~. Net4.5 main await & async applications

C #~ Asynchronous programming

Thank you for reading this article!

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.