简体   繁体   English

无法将类型'void'隐式转换为'System.Threading.Tasks.Task'

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

Here is simplified version of my code below which is generating following compilation error 这是我的代码的简化版本,下面是生成以下编译错误

Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task' 无法将类型'void'隐式转换为'System.Threading.Tasks.Task'

GetDataAsync method does not need to return anything in this case. 在这种情况下,GetDataAsync方法不需要返回任何内容。 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
}

Since you are trying to store the results of all your calls to GetDataAsync which are tasks, you shouldn't be awaiting them. 由于您试图将所有调用的结果存储到作为任务的GetDataAsync ,因此您不应该等待它们。 Simply remove the await , collect all the tasks and wait for them at the end. 只需删除await ,收集所有任务并在最后等待它们。

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 . 此外,由于您正在与Task.WaitAll同步等待,因此根本不需要使用Run async(特别是不应该只用于UI事件处理程序的async void )。

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: 如果要异步等待,则使Run async void (仅当它是UI事件处理程序时)并使用Task.WhenAll(tasks)将所有任务等待在一起:

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

The return value of an async function is Task instead of void and Task <TResult > instead of TResult. 异步函数的返回值是Task而不是void和Task <TResult >而不是TResult。

If you change your function into the following it will be correct: 如果您将功能更改为以下内容将是正确的:

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

There is one exception, an async event handler may return void: 有一个例外,异步事件处理程序可能返回void:

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

This is enough to keep your UI responsive while the task is running. 这足以在任务运行时保持UI响应。

  • You can only use await in a function if your function is async 如果函数是异步的,则只能在函数中使用await
  • async functions return Task instead of void and Task <TResult > instead of TResult. 异步函数返回Task而不是void和Task <TResult >而不是TResult。
    • the value of await Task <TResult >, is TResult. 等待任务<TResult >的价值是TResult。
    • only async functions can all other async functions. 只有异步函数才能执行所有其他异步函数。

If you have a non-async function and you want to start a task while doing other things, you can use the following code: 如果您具有非异步功能并且想要在执行其他操作时启动任务,则可以使用以下代码:

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);
}

You can even start several tasks, and while they are processing do other things and after a while wait for the tasks to finish: 你甚至可以启动几个任务,当他们正在处理其他事情时,等待一段时间后完成任务:

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.
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法隐式转换类型&#39;System.Threading.Tasks.Task - Cannot implicitly convert type 'System.Threading.Tasks.Task 无法将类型&#39;bool&#39;隐式转换为&#39;System.Threading.Tasks.Task&#39; - Cannot implicitly convert type 'bool' to 'System.Threading.Tasks.Task' 无法将类型&#39;System.Collections.Generic.List &lt;&gt;&#39;隐式转换为&#39;System.Threading.Tasks.Task &lt;&gt;&gt; - Cannot implicitly convert type 'System.Collections.Generic.List<>' to 'System.Threading.Tasks.Task<>> 无法将类型&#39;bool&#39;隐式转换为&#39;system.threading.tasks.task bool&#39; - Cannot implicitly convert type 'bool' to 'system.threading.tasks.task bool' 无法隐式转换类型&#39;System.Threading.Tasks.Task <String> “串” - Cannot implicitly convert type 'System.Threading.Tasks.Task<String> to 'string' 无法将类型“System.Threading.Tasks.Task”隐式转换为“Windows.Foundation.IAsyncAction”。 存在显式转换 - Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'Windows.Foundation.IAsyncAction'. An explicit conversion exists 无法隐式转换类型&#39;System.Threading.Tasks.Task <object> 在SignalR中从&#39;到&#39;string&#39; - Cannot implicitly convert type 'System.Threading.Tasks.Task<object>' to 'string' in SignalR 错误 CS0029:无法将类型“字符串”隐式转换为“System.Threading.Tasks.Task”<string> '</string> - Error CS0029: Cannot implicitly convert type 'string' to 'System.Threading.Tasks.Task<string>' 无法将布尔类型隐式转换为System.Threading.Tasks.Task <bool> - Cannot implicitly convert type bool to System.Threading.Tasks.Task<bool> 无法隐式转换类型&#39;System.Threading.tasks.task <Quartz.Scheduler> 至 <Quartz.IScheduler> - cannot implicitly convert type 'System.Threading.tasks.task<Quartz.Scheduler> to <Quartz.IScheduler>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM