-
-
Notifications
You must be signed in to change notification settings - Fork 9
Fix to avoid async deadlock #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
I apologize for not replying sooner - I've been a little busy and you're bringing up an issue I'm not familiar with. It seems important enough to spend a good amount of time on, and what you've done makes perfect sense. And... You are all right, I abused the Thanks!! Again :) |
|
No problem. Please take your time 😀 |
|
I've been reading about the await deadlock problem and I think the best solution would be to minimize the methods that convert from async to sync: modifying the public API, expose almost only async methods and removing unnecessary async to sync methods. |
Warning: this commit breaks some compatibility with previous versions: In Collections, these methods are removed: - `SaveChanges` -> Use `SaveChangesAsync` instead - `Save` -> Use `SaveAsync` instead - `Remove(string? id) -> Use `RemoveAsync(string? id)` instead - `Delete(string? id) -> Use `DeleteAsync(string? id)` instead - `GetId` -> Use `GetIdAsync` instead - `Contains` -> Use `ContainsAsync` instead In every Item mapped from PocketBase, these methods are removed: - `Reload` -> Use `ReloadAsync` instead - `Save` -> Use `SaveAsync` instead In DataService, these methods are removed: - `GetById<T>` -> Use `GetIdAsync<T>` instead - `SaveChanges` -> Use `SaveChangesAsync` instead
|
I made several modifications to minimize the async to sync conversion, some of these breaks compatibility with older versions. In Collections, these methods are removed:
In every Item mapped from PocketBase, these methods are removed:
In DataService, these methods are removed:
But there are still some async to sync conversions that use your hack, but to really avoid the async deadlock more work is needed. The cases are:
I think that a solution could be making a real sync version of these methods, and maybe creating async alternatives Again, thank you so much 👍🏼 |
Some part of code uses
Task.Wait()orTask.Result. But these occurs deadlock when running on Desktop application or ASP.NET Web Application, which its main thread is limited to single concurrency.To avoid that, I used
Task.Run(async () => await AsyncMethod()).GetAwaiter().GetResult().Task.Run()will execute inner async method on other thread (threadpool by default) so that deadlock will be occured in lower chance.Task.GetAwaiter().GetResult()gets the result without forgetting exceptions.Task.Wait()orTask.Resultare fire-and-forget, which forgets exceptions raised inside of async method. To re-throw the exceptions, useTask.GetAwaiter().GetResult().I tried my best to choose the best workaround to avoid deadlock. AFAIK, this is the best way to do that.
But still, there's potential risk of deadlock. (i.e. when ThreadPool hits to its concurrency limit)
So I strongly recommend to notice users about this so that users don't have to spend extra time to find out the deadlock issue.