[英]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响应。
<TResult
> instead of TResult. <TResult
>而不是TResult。
<TResult
>, is TResult. <TResult
>的价值是TResult。 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.