【问题标题】:Is this a safe way to use Async with events这是将异步与事件一起使用的安全方法吗
【发布时间】:2015-09-11 12:07:45
【问题描述】:

我以前使用任务并行库来保持 UI 线程响应,但我正在尝试切换到异步/等待以简化代码。我正在做的项目是在 WinForms 中。有一个与视图接口通信的表示层,以及一个包含实现这些接口的 winforms 表单的程序集,依赖注入将所有内容绑定在一起。在下面的具体示例中,表单有一个菜单/按钮/等,它向表示层发送新数据的请求。我忽略了异常处理以保持示例简单。

在表单代码中,我们有一个这样的事件处理程序:

private async sub DataRequest(sender as object, e as EventArgs) handles SomeButton.click
        Dim etask = New Threading.Tasks.Task(Sub() RaiseEvent DataRefreshRequest(Me, EventArgs.Empty))
        etask.Start()
        Await etask
end sub

不确定是否有更简洁的方法来等待引发事件,以上内容似乎有点笨拙

表示层使用如下代码响应此事件:

Private Async Sub HandleDataRequest() Handles _view.DataRefreshRequest
  Dim gdtask = New Tasks.Task(Of IEnumerable(Of Summary))(Function() GetDataTask())
  gdtask.Start()
  _view.Data = Await gdtask
End Sub

我们在这个项目上坚持使用 .Net 4,因此我们使用的是 Microsoft.BCL.Async。 GetDataTask 实际上是对业务层公开的实体的 Linq 查询,但如果没有 .Net 4.5,我们无法使用 .ToListAsync 执行它

我有点不确定是我在 winforms 程序集中提出事件的方式。这是正确的方法吗?它似乎工作正常,但我担心这样做会出现任何不可预见的问题。最好从一开始就做,然后在这种模式被普遍使用后发现问题。

【问题讨论】:

    标签: winforms async-await


    【解决方案1】:

    使用Task.Run 比使用Task 构造函数和Task.Start 更好。

    除此之外,我只想推荐一些 cmets。正如您所指出的,理想的解决方案是使用 ToListAsync 并使其真正异步,但鉴于您的平台,这是不可能的。

    Task.Run通常用于在后台线程上运行受 CPU 限制的代码,并且此代码不受 CPU 限制。因此,我建议您对未来的自己发表评论,以便在您升级到 .NET 4.5 时,您可以知道不再需要那些 Task.Run 调用。

    【讨论】:

    • 谢谢斯蒂芬,这让人放心。 Task.Run 肯定会整理一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 2023-04-08
    • 1970-01-01
    • 2022-01-23
    • 2012-07-22
    相关资源
    最近更新 更多