【问题标题】:Run EF6 Query in separate Thread on WinForm Button Click Event在 WinForm 按钮单击事件的单独线程中运行 EF6 查询
【发布时间】:2014-08-19 22:13:12
【问题描述】:

我对实体框架和多线程都很陌生,发现在进行大型 EF 查询时如何不锁定我的 winforms UI 有点令人困惑。

所以,假设我想在单击按钮时查询我的数据库并返回一个大型数据集,同时不锁定 UI 并且能够向我的用户发送查询正在进行中的消息,我不知道如何做到这一点,但我正在尝试!

我尝试(显然错误地)实施来自 here 的 Jon Skeet 的建议,因此我创建了以下代码,但我遇到了错误并且知道我做错了。我只是不明白如何正确地做...请任何链接/建议/示例代码将**非常*非常感谢!

我当前的代码(给出错误):

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

   Dim y As New List(Of DB_Data)

    Val1 = "Val1"
    Val2 = "Val2"

    Dim qry As task = Task.Run(Function() GetDBInfo(Val1, Val2))
    y = Await qry
End Sub

我想异步运行的方法(我不知道这是否应该是Async):

Private Async Function GetDBInfo(Val1 As String, Val2 As string) As Task(Of List(Of DB_Data))

    Dim retval As List(Of DB_Data)

    Using x As New DB_Context
        retval = Await (From rw In x.DB_Data
                         Where rw.Val1 = Val1 And
                               rw.Val2 = Val2
                         Select rw).ToListAsync
    End Using

    Return retval
End Function

再次,正如我所说,这不起作用并且可能错误 - 我只是不知道如何正确地做到这一点......任何帮助将不胜感激! - 尽管这是在 VB 中,但我对 VB/C# 解决方案同样满意。

谢谢!!

【问题讨论】:

  • 在您的按钮单击事件中 - 尝试调用 GetDBInfo(Val1, Val2)。它仍然应该返回一个您可以等待的任务
  • @JensKloster,你是对的,它确实如此,但这似乎使它与我的 UI 保持在同一个线程上并阻止它与用户交互......Task.Run() 似乎创建了一个新线程为它,不是吗??

标签: c# vb.net multithreading winforms entity-framework


【解决方案1】:

您在正确的轨道上,但您不需要带有 EF 6 的 Task.Run 方法。EF 6 带有 real 异步方法,例如 ToListAsync。这些方法在幕后使用新的 ADO.NET 异步方法,它们根本不消耗或创建任何线程。 Task.Run 旨在调用 CPU 绑定方法 more here。它还在线程池上启动一个任务来进行计算,more here。但是real async 方法根本不使用任何线程,more here。所以只需使用

var result = await (from b in db.Blogs orderby b.Name select b).ToListAsync()

足以释放 GUI 线程。也不要在这里使用阻塞方法和属性,例如等待或结果,more info

【讨论】:

  • 这就是我最初尝试过的(在我看到 Jon Skeet 的回答之前),它占用了我的 UI 线程……我只是对如何在不占用线程的情况下使用它感到困惑……
猜你喜欢
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 2015-04-19
  • 2020-10-28
相关资源
最近更新 更多