I am overriding a method, HandleRequirementAsync, so I can't modify the return type of that method. However, I am calling a method in UserManager which is async and requires an await so I had to put this code in another method.
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
EducationArmRequirement requirement)
{
if (!IsEducationGroup(context).Result)
{
return Task.FromResult(0);
}
context.Succeed(requirement);
return Task.FromResult(0);
}
protected async Task<bool> IsEducationGroup(AuthorizationHandlerContext context)
{
var userId = context.User.Identity.Name;
ApplicationUser u = await _userManager.FindByNameAsync(userId);
if (u.Group == 3 || u.Group == 4)
{
return await Task.FromResult(true);
}
return await Task.FromResult(false);
}
The code above seems to work in testing but it uses .Result to unwrap the Task to get the bool. I have seen several places that say be careful of using result. I saw this question which tries to explain why but I am not getting it.
I can't put an await in the HandleRequirementAsync method to allow this to unrap normally because then I would have to modify the return type which I can't do for this overridden method.
Am I approaching this the correct way in using the .Result or am I going to come across some issues here and if so what is another way to approach this which would work?
Any help/explanations would be much appreciated.
The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.
In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronously.
Use the Result property on the asynchronous Task, like so: // Synchronous method. void Method()
As hinted in the comments, the async modifier doesn't change the method signature - you can just add this. You can also simplify to remove usage of Task.FromResult
in both methods:
protected override async Task HandleRequirementAsync(
AuthorizationHandlerContext context,
EducationArmRequirement requirement)
{
if (await IsEducationGroup(context))
{
context.Succeed(requirement);
}
}
protected async Task<bool> IsEducationGroup(AuthorizationHandlerContext context)
{
var userId = context.User.Identity.Name;
ApplicationUser u = await _userManager.FindByNameAsync(userId);
return u.Group == 3 || u.Group == 4;
}
IsEducationGroup group function
protected async Task<bool> IsEducationGroup(AuthorizationHandlerContext context)
{
await Task.Run((){
var userId = context.User.Identity.Name;
ApplicationUser u = await _userManager.FindByNameAsync(userId);
if (u.Group == 3 || u.Group == 4)
{
return true;
}
return false;
}
})
HandleRequirementAsync function
protected override async Task HandleRequirementAsync(
AuthorizationHandlerContext context,
EducationArmRequirement requirement)
{
var result = await (!IsEducationGroup(context));
if(!result)
return;
context.Succeed(requirement);
return;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With