7

I've experienced some awkward intermittent bugs where async methods were returning void rather than Task and hence were not being awaited. to avoid such problems in the future I'm trying to create a custom resharper pattern to highlight such methods as warnings.

I've created a pattern like:

async void $methodname$($arguments$)
{
$statements$
}

(where arguments and statements allow unlimited number of each and method matches is an identifier containing 1 or more legal identifier characters)

Oddly this highlights all void methods rather than just async void methods. Can anyone see my mistake? As it seems like a common pattern to attempt to match, and google doesn't report it, I doubt if it's an outstanding issue in Reshaper 8.2.1.

P.S. I know my pattern won't match generic methods - if I can get it working for non-generic ones I'll fix that up later)

UPDATE

As highlighted in the comments I realise there are a number of false positives and false negatives that this rule would not handle. My concern here is how to get async matching to work in resharper - once that works I can look to make the rule more precise.

Typhlosaurus
  • 1,528
  • 12
  • 14
  • What if `$methodname$` needs to `await` a method call? – 48klocs Jul 14 '14 at 17:24
  • 1
    My apologies if my question is ambiguous, the reason the bugs caused by these methods were intermitent was because the methods I want to find were indeed asynchrounous and needed awaiting. The fix is to make the methods return Task and hence encourage/warn the callers to await their completion. Almost all async methods should return Task or Task. – Typhlosaurus Jul 14 '14 at 17:27
  • 3
    This won't be able to account for top level event handlers that really should be `async void` though. It also wouldn't address async lambadas, which in my experiences are the most likely causes of unintentional `async void` methods. – Servy Jul 14 '14 at 17:28
  • Indeed, but as async event handlers are rarer, at least in our code base, that's all the pattern has to handle: it should highlight some of the dangerous cases easily and enforcement of naming conventions and/or arguments can probably exclude most of the remainder. The issue here is how write a pattern that matches the async keyword, not how to distinguish some types of call from others. I agree with you about async lambdas, but having wasted most of today with a full async method this would still be useful. – Typhlosaurus Jul 14 '14 at 17:33
  • There's an open feature request for this on Resharper http://youtrack.jetbrains.com/issue/RSRP-329660 please vote on this request by using the thumbs up icon in the bottom right corner of the main block. Leaving comments would also likely be beneficial to speed this up as it's been sitting for over 2 years. – Chris Marisic Sep 09 '14 at 14:56

2 Answers2

4

You can't really do that. The way Resharper's custom patterns work evidently doesn't yet understand the async keyword (that's why it highlights all void-returning methods, and not just the async ones). You can also see this example, which matches both async and non-async methods.

What you can do is try to find async methods by searching for method names ending with "Async", like that:

async void $method$($parameters$)
{
    $statements$
}

Where the method identifier is defined by this regexp: \b\w+(Async)\b

This will allow you to replace this:

void RunAsync() // or async void RunAsync()
{
    ...
}

With this:

async Task RunAsync()
{
    ...
}
Community
  • 1
  • 1
i3arnon
  • 113,022
  • 33
  • 324
  • 344
4

We use the free ReCommended Extension for ReSharper in our projects for "async void" analysis. The extension highlights the inappropriate usages of async void and provide obvious quick fixes.

The analysis rules are described here: ReCommended-Extension wiki.

Alexander Zwitbaum
  • 4,776
  • 4
  • 48
  • 55