jwize
jwize

Reputation: 4165

How to properly call a C# async method when overriding an non-async method?

I am creating a TagHelper for a RazorPage. The TagHelper class's only requirement is that the process method get overridden.

Here is the signature (and thank you for the solution Stephen let's just assume that ProcessAsync doesn't exist so we can still answer the question).

public override void Process(TagHelperContext context, TagHelperOutput output)

The body is very simple

if(_roleService.CanRegisterAsync().Result)
{
    output.SuppressOutput();
}

I hear that deadlocks can be caused by calling .Result on async methods so I don't want to call it as written above because it seems like I could run into some trouble.

So, I change the virtual override by adding async to

public override async void Process(TagHelperContext context, TagHelperOutput output)

and the body to

if(await _roleService.CanRegisterAsync())
{
    output.SuppressOutput();
}

This compiles fine but the output.SupressOutput() doesn't to seem to have any effect anymore so I am forced to go back to the original code which seems like a bad idea.

Is there any better way to deal with this situation so I don't potentially run into deadlocks as many people talk about in other async posts?

Upvotes: 0

Views: 1639

Answers (2)

Samuel Vidal
Samuel Vidal

Reputation: 943

Apparently what you are after is the following:

if(_roleService.CanRegisterAsync().WaitAndUnwrapException())
{
    output.SuppressOutput();
}

Remark: The name of the method strongly suggests using a try/catch to handle possible exceptions

Upvotes: 0

Stephen Cleary
Stephen Cleary

Reputation: 457057

You need to create an asynchronous tag helper; in other words, override ProcessAsync instead of Process. That way you can use await:

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
  if(await _roleService.CanRegisterAsync())
  {
    output.SuppressOutput();
  }
  ...
}

Upvotes: 2

Related Questions