我有一个名为DoSomething()
的方法,它返回object
并且非常耗时。所以我想使用 async / await 让它在后台运行,同时我的GUI显示“等待响应... ”消息。
在我的通话方法中:
Task taskDoSomething = new Task(DoSomethingAsync);
taskDoSomething.Start();
taskDoSomething.Wait();
// continue the program
我的DoSomethingAsync
方法:
private async void DoSomethingAsync()
{
Object result = await DoSomething();
}
但我收到错误:
无法等待[ObjectType]
[ObjectType]
是我自己创建的一种对象。我只是用上面的对象不要混淆读者。
请让我知道我做错了什么,让我摆脱BackgroundWorker
的分散处理。
答案 0 :(得分:10)
我认为您误解了async
和await
的工作原理。如果DoSomething()
是一个长期运行的方法,不是设计用于异步,您可能只想在不同的线程中执行此操作,例如:通过开始一项单独的任务:
Task<object> task = Task.Run<object>(DoSomething);
请注意,DoSomething
表示无法与用户界面进行互动,因为它会在不同的主题上。
然后,如果您愿意,可以await
该任务 - 但仅限于异步方法。在不了解更多背景的情况下,很难提出更具体的建议。
根据您的评论,您可能会有以下内容:
private async void HandleButtonClick(object sender, EventArgs e)
{
Task<object> task = Task.Run<object>(DoSomething);
object result = await task;
status.Text = "I've done something";
// Use the result?
}
答案 1 :(得分:5)
如果DoSomething
是同步的(它似乎是)并且您想将其卸载到另一个线程以保持UI响应,则应使用Task.Run
:
async Task DoSomethingAsync()
{
var result = await Task.Run(() => DoSomething());
}
除非在事件处理程序中,否则您也不应使用async void
没有理由直接创建任务。让DoSomethingAsync
返回Task
或完全删除该方法并直接使用Task.Run
。
但是,如果DoSomething
本质上是异步的,则应使用async-await
实现它,并让它隐式返回任务。