【问题标题】:Wait for async method without blocking the thread等待异步方法而不阻塞线程
【发布时间】:2013-06-18 09:39:53
【问题描述】:

如何在SubmitWorkitem() 方法之后执行UpdateTasklist() 方法而不阻塞线程?

private async void SubmitWorkitem(Workitem workitem)
{
    await Task.Run(() => this.SubmitWorkitem(workitem));

    //UpdateTasklist() should be executed after SubmitWorkitem() method.
    //How can i achieve this without blocking the UI thread?
    var locator = new ViewModelLocator();
    locator.Task.UpdateTasklist();
}

编辑:

UpdateTasklist() 方法连接到 wcf 网络服务并请求所有打开的工作项。在SubmitWorkitem() 方法中提交的工作项仍然是回复的一部分。我认为那是因为UpdateTasklist() 是在工作项提交完成之前执行的。

注意UpdateTasklist()也是一个异步方法

【问题讨论】:

  • 要么定义回调,要么将UpdateTaskList 放入异步任务中
  • 将我的答案重新编辑为您的编辑
  • 哦,刚刚注意到这是async void;是的……不要那样做;这简直是​​危险的。该功能存在以允许事件处理程序;你永远不应该写一个async void 方法。它应该是async Taskasync Task<SomeType>
  • 我想我今天学到了一些东西,谢谢你

标签: c# wpf asynchronous .net-4.5 async-await


【解决方案1】:

重要提示:请勿编写ASYNC VOID 方法(除非您正在编写事件处理程序)

剩下的:

这已经是您的代码中发生的事情了;这就是await 的意思;基本上,您的 DifferentClass.UpdateTasklist(); 方法作为 延续 的一部分发生,当且仅在第一个任务 (this.SubmitWorkitem(workitem)) 完成时调用。

在您的编辑中, 缺少一个步骤:您应该await 第二种方法,否则该方法无法报告完成/失败(IIRC 编译器也会唠叨您):

private async Task SubmitWorkitem(Workitem workitem)
{
    await Task.Run(() => this.SubmitWorkitem(workitem));
    var locator = new ViewModelLocator();
    await locator.Task.UpdateTasklist();
}

【讨论】:

  • 该方法因此必须是无效的:this.SubmitCommand = new RelayCommand(this.SubmitWorkitem, this.CanSubmit);
  • @Joel 嗯,我想那必须与事件处理程序放在同一个括号内;也许正确的指导是“除非你别无选择,否则不要编写 async void 方法” - 但是,请记住,这里的跑步者将 不知道 你的方法是否已经完成 - 只要就框架而言,该方法将在到达第一个await 时“结束”(如果我们假设等待的操作实际上并未同步完成,这可能会发生,但在这里听起来不太可能)。重点是......也许会遇到麻烦
  • @Joel:在这种情况下,您确实需要 async void ICommand.Execute 实现,但您可以将其“隐藏”在 async Task 方法后面。这为您提供了一个更好的 API,您可以直接使用它,例如,在单元测试时。一个简单的AsyncCommand 类型是here,我写了一个更复杂的here
猜你喜欢
  • 1970-01-01
  • 2015-12-04
  • 2020-01-17
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2023-03-22
  • 1970-01-01
相关资源
最近更新 更多