StephenCleary / AsyncEx

A helper library for async/await.
MIT License
3.49k stars 358 forks source link

[Question] .WaitAndUnwrapException() vs AsyncContext and potential deadlock #267

Closed MiloszKrajewski closed 1 year ago

MiloszKrajewski commented 1 year ago

I would like to say that I find this library and inspiration. As an author of some open source libraries sometimes I just need one method or class (let's say cancelationToken.AsTask()) but I don't want to create whole new dependency so I decide not to import AsyncEx (sorry!) but I still check, "is and potentially how Stephen Cleary does it".

One thing intrigued me recently.

In TaskExtensions you use .GetAwaiter().GetResult() only.

This, of course has a long history, of deadlocking on certain (?) SynchronisationContexts,, ie ASP.NET MVC and no longer deadlocking with .NET Core.

However, this library can be used by .NET 4.6.1 so technically is still can be run in all those deadlock prone environments (WPF let's say).

Is there any way to detect chance of deadlock (like Debig.Assert(SynchronisationContect.Current == null))? Would it be enough? Am I horribly mistaken? Maybe I should use AsyncContext?

But this is much slower and GetAwaiter().GetResult() is actually working for my test cases. It seems that both, people at Microsoft use it in Azure SDK and people at HashCorp in Vault SDK.

Do they know something I don't?

I know, it is a lot of questions and I feel bad bothering you, but maybe you will find some time.

Anyway, my main usage is: .NET Core DI Container (as classes are meant to be resolved synchronously, while data to resolve those classes may be resolved asynchronously).

MiloszKrajewski commented 1 year ago

I think this https://learn.microsoft.com/en-us/archive/msdn-magazine/2015/july/async-programming-brownfield-async-development answer all the questions and I should be ashamed to ask them ;-) Although, as it might be useful to someone I will leave this link.

StephenCleary commented 1 year ago

sometimes I just need one method or class (let's say cancelationToken.AsTask()) but I don't want to create whole new dependency so I decide not to import AsyncEx (sorry!) but I still check, "is and potentially how Stephen Cleary does it".

I do the same thing sometimes, myself. The code is MIT-licensed, so copy freely!

I should be ashamed to ask them ;-)

Not at all! There are lots of answers out there, but they're not always easy to find!