I made a somewhat large application that works well, except for its UI (winforms) freezes when using webclient to retrieve data from web (link is um... not the fastest), or data connection to retrieve queries from the database (which is stored in a far, slow server - can't avoid it).
So I thought of taking advantage of async methods, in order user can move, minimize and click the window without OS getting nervous and tagging it as "not responding".
I don't want my code to do nothing else in-between those lenghty operations, just keep UI responsive (I know I should disable controls to prevent user of asking something else, or the same afgain, before first operation completes).
But I have no experience whatsoeever with async methods, and my first test attempt was this:
Public Function GetDatatableUIblocked() As DataTable
Dim retTable As New DataTable
Dim connection As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\lanserver\storage\DB.accdb;Persist Security Info=False;")
Dim command = connection.CreateCommand()
command.CommandText = "SELECT * FROM bdPROC;"
connection.Open()
Dim reader = command.ExecuteReader
retTable.Load(reader)
connection.Close()
Return retTable
End Function
Public Function GetDatatableUIfree() As DataTable
Dim retTable As New DataTable
Dim connection As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\lanserver\storage\DB.accdb;Persist Security Info=False;")
Dim command = connection.CreateCommand()
command.CommandText = "SELECT * FROM bdPROC;"
connection.Open()
Dim readerTask = command.ExecuteReaderAsync()
readerTask.Start() '<=========================== EXCEPTION HAPPENS HERE
Do
Application.DoEvents()
Loop Until readerTask.IsCompleted OrElse readerTask.IsFaulted
Dim reader = readerTask.Result
retTable.Load(reader)
connection.Close()
Return retTable
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ProgressBar1.Visible = True
Dim dt = GetDatatableUIblocked()
ProgressBar1.Visible = False
DataGridView1.DataSource = dt
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
ProgressBar1.Visible = True
Dim dt = GetDatatableUIfree()
ProgressBar1.Visible = False
DataGridView1.DataSource = dt
End Sub
However, I get an exception when running readerTask.Start()
, it says something like 'Start cannot be called in a task which is already complete' (I'm translating, my VS is not in English).
I checked some threads here in SO but honestly I wasn't able to grasp the concept and apply it to my problem, so I humbly ask for help. Thank you very much!