Reputation: 59
This is my requirement:
On a button click I need to get the data from database and populate in a datagridview, for which I'm using a function. As the retrieval may take a long time and I want to use the UI meanwhile, I want this function to run in a separate thread.
For this, I'm using async callback. But between the begininvoke()
and endinvoke()
function. I'm not writing any code (I don't know what to write to make the UI respond).
The datagridview is getting populated correctly but the UI is blocked when I'm trying to access it when the function is retrieving the data.
Upvotes: 0
Views: 1942
Reputation: 59
First of all, i should create asynccallback function in the UI form itself, not in middle level which is, in my case , DataMgr. Also, i should add the last two parameters for begininvoke function with appropriate values where i have passed null values. It should be
MethodDelegate dlgt = new MethodDelegate(DataMgr.countIssuingEntities);
TempValueHolder tmp = new TempValueHolder();
AsyncCallback cb = new AsyncCallback(MyAsyncCallBack);
IAsyncResult ar = dlgt.BeginInvoke(issueGroupId, element.ControlType, (EvaluatingEntityCombo.SelectedItem as CIQHydCore.RefData.RefDataInfo).Id, (IssuingEntityCombo.SelectedItem as CIQHydCore.RefData.RefDataInfo).Id, str1, str2,**cb,dlgt**);
and in MyAsyncCallBack function we need to populate the datgridview with the retrieved values from the end
Upvotes: 0
Reputation: 2163
If you are using a loop
to Populate your DataGridView
, You can use the Method Application.DoEvents()
inside your loop
to make your UI remain Responsive during the population of the DataGridView
.
As you stated the problem is not the loop, I think the best approach will be using the BackgroundWorker
class.
Where you can populate the DataGridView
in the DoWork()
event of the BackgroundWorker
And you can start the BackgroundWorker.DoWork()
event during the button_click
event of your Code!
Upvotes: 0
Reputation: 39085
I'd recommend not to start the long running operation from the UI thread. Start another thread first, and then do the long running operation in that separate thread. When it is done, post the results back to the UI using the Form.Invoke() method. This way, the UI thread is not affected directly.
Instead of creating another thread by hand, you can also use a construct like BackgroundWorker.
If you do start the long running operation from the UI thread, you'd need to call Application.DoEvents() periodically (e.g. inside a loop). However, if the long running operation is an IO intensive -- meaning you are waiting for an IO operation most of the time -- then you won't get to call Application.DoEvents() as often as you'd like. This will make the UI seem less responsive or jerky. The seperate thread, as I mentioned above, is a better way in this regard.
Upvotes: 1