-1

I am newbie to asynchronous programming in C#. In general I understand concepts of asynchronous programming but I am not completely down with all the details so I got this question.

What is the conceptual difference between these two methods?

        public async Task<int> Action1()
        {
          // ...
        }

        public Task<int> Action2()
        {
          // ...
        }

How should I think about each of these when I see them in code? Eg. what mental model should come to my mind? And in what use-cases should I use one over the other (if there are any preferences)?

Edit: Does this code make sense:

    public async Task Action1()
    {
      await someAsyncMethod(); // do nothing with result
    }

    public Task Action2()
    {
      return Action1()
    }
mlst
  • 2,688
  • 7
  • 27
  • 57
  • 1
    You are only allowed to use await in methods marked as async. – NineBerry Aug 11 '21 at 22:31
  • this question isn't really that good, your real question is really asking about what the keyword "async" means, and all the parts about how to "think" about it and what mental model to use is really highly opinionated. – Keith Nicholas Aug 11 '21 at 22:59
  • 2
    You may find this interesting: [Eliding Async and Await](https://blog.stephencleary.com/2016/12/eliding-async-await.html) – Theodor Zoulias Aug 12 '21 at 01:34
  • Does this answer your question? [How and when to use ‘async’ and ‘await’](https://stackoverflow.com/questions/14455293/how-and-when-to-use-async-and-await) – TylerH Aug 12 '21 at 15:22

2 Answers2

2

The way I like to think about it is this:

In other words, async affects how a method is implemented, but is not part of the method's signature.

Taking your example, this is how the signatures appear in the IL:

.method public hidebysig 
    instance class [System.Private.CoreLib]System.Threading.Tasks.Task`1<int32> Action1 () cil managed 

.method public hidebysig 
    instance class [System.Private.CoreLib]System.Threading.Tasks.Task`1<int32> Action2 () cil managed 

As to when to use async (for the method implementation), my quick rule of thumb is to use async when the method I am writing needs to call and wait for another method that returns a Task. In other words, when I need to use await in the implementation of a method.

Several other questions/answers try and address this better than I can, though:

omajid
  • 14,165
  • 4
  • 47
  • 64
  • Thanks for the thorough answer but can you please address one important point that I am interested in. Does it make any sense to have method that returns `Task` without having the `async` before it? Eg. in my original post I the second method: `public Task Action2() { ... }`, and this method doesn't have `await` inside. In particular does this make sense to do in ASP.NET Core actions or razor pages? – mlst Aug 12 '21 at 10:25
  • I've updated my OP to Action2 calling Action1 to show what I mean. – mlst Aug 12 '21 at 10:32
  • See https://drakelambert.dev/2020/07/Asynchronous-Method-Without-async-in-C%23.html#missing-methods-in-the-stack-trace. There's definitely a reason to do it, but you need to think through what it means. – omajid Aug 12 '21 at 20:55
0

The difference is that if you don't specify to the method that it's going to be asynchronous with the reserved word "async" then you won't be able to make asynchronous calls. Even if you indicate Task. If you try to make a method and inside you indicate await but in the prototyping of the method you do not indicate async, then it will indicate that you have an error.