在单独的线程上运行EF6查询WinForm按钮单击事件

时间:2014-08-19 13:16:36

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

我对Entity Framework和多线程都很陌生,并且发现在制作大型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#解决方案也很满意。

谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

足以释放GUI线程。此外,请勿在此处使用阻止方法和属性,例如等待或结果more info