-
Notifications
You must be signed in to change notification settings - Fork 195
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
Deadlocks inside ASP.NET MVC applications #821
Comments
Adding sample project for easier reproduction scenario - |
Unfortunately no, I thought so, but the code flow doesn't go through those configureawait(true) (to be sure I also debugged with fixed |
hmm, thanks for the details @s-KaiNet . I'm back at work as of today, will have some time the coming days to dig into this. Wondering if this would also happen when using .NET 6? |
It works fine in .NET 6 because there no |
@s-KaiNet : running the sync code in a dedicated thread would prevent the deadlock. Would that be work around for you? public ActionResult Contact()
{
Task.Run(() =>
{
var services = new ServiceCollection();
services.AddPnPCore(options =>
{
// PnP Office 365 Management Shell = "31359c7f-bd7e-475c-86db-fdb8c937548e";
options.DefaultAuthenticationProvider = new CredentialManagerAuthenticationProvider("31359c7f-bd7e-475c-86db-fdb8c937548e", TenantId, CredName);
options.PnPContext.GraphFirst = false;
});
var provider = services.BuildServiceProvider();
var scope = provider.CreateScope();
var pnpContextFactory = scope.ServiceProvider.GetRequiredService<IPnPContextFactory>();
using (var pnpContext = pnpContextFactory.Create(new Uri(SiteUrl)))
{
var list = pnpContext.Web.Lists.GetByServerRelativeUrl(ListUrl);
ViewBag.Message = list.Title;
}
});
return View();
} |
Yeah, that would work. I just try to understand why we have so weird behavior in the "normal" sync case. SynchronizationContextRemover also works in this case, but maybe it's not the best solution. |
Not sure if we need to change PnP Core SDK for this purpose @s-KaiNet , but I'm happy to listen to your arguments if you feel changes are needed. We encourage folks to use the async PnP Core SDK methods and the main usage of the library is with .NET Core and .NET 5/6 based applications. I've checked the Azure .NET SDKs as they offer sync and async as well and they use the same GetAwaiter().GetResult() approach. Their docs: https://azure.github.io/azure-sdk/dotnet_introduction.html#sync-and-async explain that and also point to an article articulating the potential async deadlocks this can lead to. We could consider wrapping all our method().GetAwaiter().GetResult() calls via Task.Run(), (see https://stackoverflow.com/a/59019473) but that could still result in threadpool starvation issues under load. Think it's better that developers that need to use sync implement Task.Run() themselves (like shown above and below). What if we clearly spell this out in documentation: if you're stuck with deadlocks when using sync method calls then consider wrapping them in Task.Run()? using (var pnpContext = Task.Run(() => pnpContextFactory.CreateAsync(new Uri(SiteUrl))).GetAwaiter().GetResult())
{
var list = Task.Run(() => pnpContext.Web.Lists.GetByServerRelativeUrlAsync(ListUrl)).GetAwaiter().GetResult();
ViewBag.Message = list.Title;
} |
I also don't think we need change anything in the library. My scenario is more about some legacy stuff like old asp.net MVC. I though that maybe I did something wrong and the fix is fairly simple. But anyway as I have some workarounds I'm ok with that. I think we can close the issue. |
@s-KaiNet : Did add a small note to our docs (https://pnp.github.io/pnpcore/using-the-sdk/basics-async.html) for future reference. Closing the issue now. Thanks for pushing this issue as it helps to improve the quality of the SDK. |
Category
Describe the bug
ASP.NET MVC (.NET Framework-based) application deadlocks when using the library inside synchronous methods.
Steps to reproduce
Contacts
action method insideHomeController
:GetByServerRelativeUrl
.The given code is used just to illustrate the problem - PnP Core SDK methods are used in a "sync" manner and it leads to the deadlock. Instead
GetByServerRelativeUrl
you can useLoad
methods or others. This can be fixed by making controllers methodsasync
, but in our case, we use it not in controllers, but deep inside business logic which cannot be madeasync
.I debugged I found that deadlock happens exactly at this line. Interesting enough, in my code sample, at line
pnpContextFactory.Create
the code also sends the request usingbase.SendAsync
, but it doesn't deadlock, but only atGetByServerRelativeUrl
afterward.Expected behavior
I'm not sure what is the expected behavior, because to my understanding
ConfigureAwait(false)
inside the library helps with the deadlocks inside ASP.NET MVC applications. But for some reasonsbase.SendAsync
deadlocks when used fromGetByServerRelativeUrl
orLoad
methods. As I see it, it shouldn't deadlock, but maybe the problem is completely different.Environment details (development & target environment)
The text was updated successfully, but these errors were encountered: