0

I'm confused when to one would use async inside a method. Based on my tests both of these methods work the same way. When would you use one vs. other?

        // Returns a task which can be awaited in the controller
        private Task<int> RunAsyncTask1()
        {
            Task<int> task = Task.Run(() =>
            {
                int result = CalculateMeaningOfLife();
                return result;
            });

            return task;
        }

        // Returns an actual value - it too, can be awaited in the controller
        private async Task<int> RunAsyncTask2()
        {
            var task = await Task.Run(() => {
                int result = CalculateMeaningOfLife();
                return result;
            });

            return task; 
        }

Controller:

    public async Task<ActionResult> Index()
    {
        Task<int> task = RunAsyncTask1(); // Without await - will continue and not wait for result 
        int result = await RunAsyncTask1(); // Main Thread put back in Thread Pool, will wait for result

        Task<int> task = RunAsyncTask2(); // Without await - will continue and not wait for result
        int result = await RunAsyncTask2(); // Main Thread put back in Thread Pool, will wait for result

        return View();
    }

Is the only benefit of having "await" keyword WITHIN a method (RunAsyncTask2()) so that you can set up multiple continuations within that method?

BobSwanson
  • 423
  • 2
  • 5
  • 18
  • 1
    `await` is useful when you are executing more than one task and one is dependant on the other. Also if you were to have more code after the `var task = //...` initialization, `await` guarantees it will get executed *after* the task completes. Of course, if you are just returning the task, then there's no need for `await` in this case. – Matias Cicero Sep 29 '16 at 16:24
  • 1
    The difference between the two is one is "here's a task: blah blah blah" and the other is "here's a task: perform this task: blah blah blah". There is no good reason to prefer the latter. A task whose sole content is doing a task is not an interesting task. – Eric Lippert Sep 29 '16 at 16:33
  • Similarly, you might wonder whether it ever makes sense to have an async method that returns `Task>`. Typically it does not, though this is possible. *Logically* it is always the case that you can "collapse" monads/comonads. That is, a `Maybe>` is *logically* the same as a `Maybe`. A `Task>` is *logically* the same as a `Task`. A `Lazy>` is *logically* the same as `Lazy` -- in each, the sense being that when you get the int out of the thing, it's the same int regardless of the number of wraps. – Eric Lippert Sep 29 '16 at 16:37
  • `When would you use one vs. other?` You would use neither. Avoid `Task.Run` on ASP.NET; it doesn't give you *any* benefit here and only makes your code less efficient and less scalable. – Stephen Cleary Sep 29 '16 at 22:39
  • @Stephen- What do you mean? I though I could run asynchronous processes in MVC. Or at least in Parallel..ie. getting stuff from Db, while processing something else etc – BobSwanson Sep 30 '16 at 15:01
  • @BobSwanson: Asynchronous is fine. `Task.Run` is not asynchronous. I don't recommend parallel code on ASP.NET because it can seriously impact your scalability. – Stephen Cleary Sep 30 '16 at 16:01
  • what about the following, if the tasks are unrelated, wouldn't it improve performance? // Executes SumX, SumY and SumZ in parallel Parallel.Invoke(new ParallelOptions {CancellationToken = cts.Token}, () => sumX = SumX(cts.Token), () => sumY = SumY(cts.Token), () => sumZ = SumZ(cts.Token)); – BobSwanson Sep 30 '16 at 16:13

0 Answers0