Isaac
Isaac

Reputation: 2412

Why using Task.Run on async function doesn't return Task<Task<T>>

Consider the following code snippet in which the MyMethod and its asynchronous version MyMethodAsync is called in different ways:

using System;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static int MyMethod()
        {
            System.Threading.Thread.Sleep(1000);

            return 42;
        }

        static async Task<int> MyMethodAsync()
        {
            await Task.Delay(1000);

            return 42;
        }

        static void Main(string[] args)
        {
            var result1 = MyMethod(); // int
            var result2 = MyMethodAsync(); // Task<int>
            var result3 = Task.Run(() => MyMethod()); // Task<int>
            var result4 = Task.Run(() => MyMethodAsync()); // Task<int>
        }
    }
}

In each case, I have commented the return type.

The question is why the type of result4 is Task<int> too? Shouldn't it be Task<Task<int>>?

BTW, is there any case that calling an async method by Task.Run could be beneficial?

Upvotes: 1

Views: 104

Answers (1)

Douglas
Douglas

Reputation: 54887

The reason it returns a Task<int> is that you're calling the Task.Run(Func<Task<TResult>>) overload, which returns a task that serves as a proxy for the task returned by your function. If you wanted to use the original overload, you could specify the generic type parameter:

var result3 = Task.Run(() => MyMethod()); // Task<int>
var result4 = Task.Run(() => MyMethodAsync()); // Task<int>
var result5 = Task.Run<Task<int>>(() => MyMethodAsync()); // Task<Task<int>>

As for your second question: using Task.Run on an asynchronous operation is beneficial when the said operation also has a synchronous part, which thereby gets executed on a background thread, rather than blocking your original thread. For example, StreamWriter.WriteAsync might need to serialize the string to a byte array before writing it asynchronously to disk. The serialization is done synchronously, and might benefit from being run on a background thread.

Upvotes: 1

Related Questions