无法将类型 'void' 隐式转换为 'System.Threading.Tasks.Task'
Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task'
下面是我的代码的简化版本,它会生成以下编译错误
Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task'
GetDataAsync 方法在这种情况下不需要 return 任何东西。我怎样才能使它 return 成为我可以等待的任务?
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
}
由于您试图存储对 GetDataAsync
的所有调用结果,这些调用是任务,因此您不应该等待它们。只需删除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);
}
此外,根本不需要使 Run
异步(尤其是 async void
,它只应用于 UI 事件处理程序),因为您正在与 [= 同步等待16=].
如果你想异步等待然后制作 Run
async void
(仅当它是一个 UI 事件处理程序时)并使用 Task.WhenAll(tasks)
一起等待所有任务:
static async void Run()
{
await Task.WhenAll(new[] {"a", "b", "c", "d", "e", "f"}.Select(GetDataAsync));
}
异步函数的 return 值是 Task 而不是 void 和 Task<TResult
> 而不是 TResult。
如果您将函数更改为以下内容,它将是正确的:
private static async Task Run()
{
...
await ...
}
There is one exception, an async event handler may return void:
private async void OnButton1_clicked(object sender, ...)
{
await Run();
}
这足以让您的 UI 在任务 运行 时保持响应。
- 如果你的函数是异步的,你只能在函数中使用 await
- 异步函数 return Task 而不是 void 和 Task
<TResult
> 而不是 TResult。
- await Task
<TResult
> 的值为 TResult。
- 只有异步函数可以使用所有其他异步函数。
如果你有一个非异步功能,并且你想在做其他事情的同时启动一个任务,你可以使用下面的代码:
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.
}
下面是我的代码的简化版本,它会生成以下编译错误
Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task'
GetDataAsync 方法在这种情况下不需要 return 任何东西。我怎样才能使它 return 成为我可以等待的任务?
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
}
由于您试图存储对 GetDataAsync
的所有调用结果,这些调用是任务,因此您不应该等待它们。只需删除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);
}
此外,根本不需要使 Run
异步(尤其是 async void
,它只应用于 UI 事件处理程序),因为您正在与 [= 同步等待16=].
如果你想异步等待然后制作 Run
async void
(仅当它是一个 UI 事件处理程序时)并使用 Task.WhenAll(tasks)
一起等待所有任务:
static async void Run()
{
await Task.WhenAll(new[] {"a", "b", "c", "d", "e", "f"}.Select(GetDataAsync));
}
异步函数的 return 值是 Task 而不是 void 和 Task<TResult
> 而不是 TResult。
如果您将函数更改为以下内容,它将是正确的:
private static async Task Run()
{
...
await ...
}
There is one exception, an async event handler may return void:
private async void OnButton1_clicked(object sender, ...)
{
await Run();
}
这足以让您的 UI 在任务 运行 时保持响应。
- 如果你的函数是异步的,你只能在函数中使用 await
- 异步函数 return Task 而不是 void 和 Task
<TResult
> 而不是 TResult。- await Task
<TResult
> 的值为 TResult。 - 只有异步函数可以使用所有其他异步函数。
- await Task
如果你有一个非异步功能,并且你想在做其他事情的同时启动一个任务,你可以使用下面的代码:
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.
}