4

In documentation here: http://msdn.microsoft.com/en-us/library/hh191443.aspx it indicates that:

If an async method doesn’t use an await operator to mark a suspension point, the method executes as a synchronous method does, despite the async modifier. The compiler issues a warning for such methods.

I believe this is the warning:

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Then, in a different, referenced link, http://msdn.microsoft.com/en-us/library/windows/apps/hh994635.aspx, the example it shows is as follows:

public class Example
{
    // ...
    private async void NextMove_Click(object sender, RoutedEventArgs e)
    {
        await Task.Run(() => ComputeNextMove());
        // Update the UI with results
    }

    private async Task ComputeNextMove()
    {
        // ...
    }
    // ...
}

Here, I'll assume that ComputeNextMove is basically a synchronous method, itself, not calling await. That then would seem to contradict the issuance of a compiler warning (unless it's a bad example...)

If I'm not calling a .net Async method at the END of my asynchronous call stack, like HttpClient.GetStringAsync and I do want to implement some concrete "long running" synchronous logic, is there a more proper way to do it?

Perhaps my assumption is incorrect, and ComputeNextMove could be declared as private void ComputeNextMove() which would yield no warnings.

3
  • 1
    This is confusing. You're calling Task.Run(Func<Task>), which waits for the returned task. Commented Feb 11, 2014 at 16:44
  • The Task itself calls await. Commented Feb 11, 2014 at 16:44
  • "If code has async with no await, it's synchronous" - shows code with both: "I assume it is synchronous." I'm lost. Commented Feb 11, 2014 at 16:45

1 Answer 1

13

Yes, it's just a bad example.

If ComputeNextMove is truly just a synchronous method which doesn't really do anything asynchronously (as the description suggests), it shouldn't be declared as async. It should instead be private void ComputeNextMove().

ComputeNextMove will still execute on a background thread due to the use of Task.Run.

I would quite possibly use a method group conversion instead of a lambda expression here:

await Task.Run((Action) ComputeNextMove);
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Jon, it's probably a very silly question, but most examples I've seen show writing an async method that intrinsically calls a .net async method, and I was a little fuzzy on the case where I might want to write such a method. Based on the responses (and decompiling HttpClient.GetStringAsync as an example), it seems like it comes down to a Task somewhere that's awaited.
@Novox: It isn't always a task, although it usually is. And yes, relatively few people will will be writing their own "primitive" async methods. You usually end up going down - possibly via many other async methods - to framework *Async methods... or creating a task for specifically synchronous work that you just don't want to do on the current thread.
In your answer, you used method group coversion instead of a lamba expression. Why so ? Are there performance benefits for doing that?
@BilalFazlani: Nope, it was just a bit simpler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.