1

I am very new to both Entity Framework AND multi-threading and finding it a bit confusing how to not lock up my winforms UI while making a large EF query.

So, suppose I want to, on a button click, query my database and return a large dataset while not locking up the UI and being able to send messages to my user that the query is in progress, I don't know how to do this AT ALL, but am trying!!

I tried to (obviously incorrectly) implement Jon Skeet's advice from here, and so I've created the following code, but I'm getting errors and know I'm doing it wrong. I just don't understand how to do it right... PLEASE any links / advice / sample code would be **VERY* much appreciated!!

My current code (giving errors):

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

The method I want to run Asynchronously (I have no clue if this should be Async or not) :

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

Again, as I said, this is not working and could be dead wrong - I just don't know any better how to do it right... Any help would be greatly appreciated! - And even though this is in VB, I'm equally comfortable with VB / C# solutions.

Thanks!!

Community
  • 1
  • 1
John Bustos
  • 19,036
  • 17
  • 89
  • 151
  • 1
    In your button click event - try and just call `GetDBInfo(Val1, Val2)`. It should still return a Task that you can await – Jens Kloster Aug 19 '14 at 13:32
  • @JensKloster, you're right it does, but that seems to keep it on the same thread as my UI and blocks it from user interaction... the `Task.Run()` seemed to create a new thread for it, no?? – John Bustos Aug 19 '14 at 15:54

1 Answers1

1

You are on the right track but you don't need the Task.Run method with EF 6. EF 6 comes with real async methods such as ToListAsync. These methods are using new ADO.NET's async methods behind the scene and they don't consume or create any threads at all. Task.Run is designed to call CPU-bound methods, more here. Also it starts a task on the thread pool to do the calculations, more here. But real async methods do not use any threads at all, more here. So just using

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

is enough to free the GUI thread. Also don't use blocking methods and properties here such as wait or result, more info.

VahidN
  • 18,457
  • 8
  • 73
  • 117
  • That's what I tried originally (before I saw Jon Skeet's answer) and it tied up my UI thread... I just got confused with how to use this without tying up the thread.... – John Bustos Aug 19 '14 at 13:43