C# – Cannot implicitly convert type ‘void’ to ‘System.Threading.Tasks.Task’

async-awaitcnettasktask-parallel-library

Here is simplified version of my code below which is generating following compilation error

Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task'

GetDataAsync method does not need to return anything in this case. How can I make it return a Task that I can wait on?

static async void Run()
{
    List<string> IDs = new List<string>() { "a", "b", "c", "d", "e", "f" };
    Task[] tasks = new Task[IDs.Count];
    for (int i = 0; i < IDs.Count; i++)
        tasks[i] = await GetDataAsync(IDs[i]);

    Task.WaitAll(tasks);    
}

async static Task GetDataAsync(string id)
{
    var data = await Task.Run(() => GetDataSynchronous(id));
    // some other logic to display data in ui
}

Best Answer

Since you are trying to store the results of all your calls to GetDataAsync which are tasks, you shouldn't be awaiting them. Simply remove the await, collect all the tasks and wait for them at the end.

static void Run()
{
    List<string> IDs = new List<string>() { "a", "b", "c", "d", "e", "f" };
    Task[] tasks = new Task[IDs.Count];
    for (int i = 0; i < IDs.Count; i++)
        tasks[i] = GetDataAsync(IDs[i]);

    Task.WaitAll(tasks);    
}

Also, there's no need to make Run async at all (especially not async void which should only be used for UI event handlers) since you are waiting synchronously with Task.WaitAll.

If you want to wait asynchronously then make Run async void (only if it's a UI event handler) and use Task.WhenAll(tasks) to wait all tasks together:

static async void Run()
{
    await Task.WhenAll(new[] {"a", "b", "c", "d", "e", "f"}.Select(GetDataAsync));
}