无法在异步调用中等待对象

时间:2014-11-12 14:34:16

标签: c# winforms asynchronous async-await

我有一个名为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的分散处理。

2 个答案:

答案 0 :(得分:10)

我认为您误解了asyncawait的工作原理。如果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实现它,并让它隐式返回任务。