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

Here is a simplified version of my code below that generates the following compilation error

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

In this case, GetDataAsync should not return anything. How can I get him to return a task that I can wait for?

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
}
+4
source share
2 answers

Since you are trying to save the results of all your calls to GetDataAsync, which are tasks, you should not expect them. Just delete 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);    
}

, Run async ( async void, UI), Task.WaitAll.

, Run async void ( UI) Task.WhenAll(tasks) :

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

async- void Task <TResult > TResult.

, :

private static async Task Run()
{
    ...
    await ...
}

, async void:

private async void OnButton1_clicked(object sender, ...)
{
    await Run();
}

, .

  • , isync
  • async void Task <TResult > TResult.
    • <TResult > , TResult.
    • async async.

non-async , , :

private void MyFunction()
{
    // do some processing
    // start a separate task, don't wait for it to finish:
    var myTask = Task.Run( () => MyAsyncFunction(...))
    // while the task is running you can do other things
    // after a while you need the result:
    TResult result = await myTask;
    ProcessResult(result);
}

, :

private async void OnButton1_clicked(object sender, ...)
{
    var Tasks = new List<Task>();
    for (int i=0; i<10; ++i)
    {
        Tasks.Add(Run());
    }
    // while all tasks are scheduled to run, do other things
    // after a while you need the result:
    await Task.WhenAll(tasks);
    // Task.WhenAll(...) returns a Task, so await Task.WhenAll returns void
    // async functions that return Task`<TResult`> has a Result property 
    // that has the TResult value when the task if finished:
    foreach (var task in tasks)
    {
        ProcessResult(task.Result);
    }
    // not valid for your Run(), because that had a Task return value.
}
+1

All Articles