Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would you call async method in a method which cannot be async in C# without using .Result

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.

like image 459
Xaxum Avatar asked Jul 31 '16 05:07

Xaxum


People also ask

What if async method is not awaited?

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.

Can we call async method without await?

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.

Can we call asynchronous method from another synchronous method in C#?

Use the Result property on the asynchronous Task, like so: // Synchronous method. void Method()


2 Answers

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;
}
like image 86
Charles Mager Avatar answered Oct 18 '22 22:10

Charles Mager


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;
        }
like image 38
Vinoth Rajendran Avatar answered Oct 18 '22 21:10

Vinoth Rajendran