简体   繁体   中英

WinForms Control.BeginInvoke asynchronous callback

I have a number of Janus grid controls that need to be populated on an application startup.

I'd like to load these grids on different threads to speed startup time and the time it takes to refresh these grids. Each grid is on a seperate tab. Ideally I'd like to use Control.BeginInvoke on each grid and on the grid load completing the tabs will become enabled.

I know with Delegates you can do a Asynchronous callback when using BeginInvoke, so I could enable the tabs in the asynchronous callback, however when using Control.BeginInvoke this is not possible. Is there a way to do asynchronous callbacks using Control.BeginInvoke or possibly a better solution?

So far I have:

public delegate void BindDelegate(IMyGrid grid);

private IAsyncResult InvokeBind(IMyGrid grid)
{
  return ((Control)grid).BeginInvoke(
    new BindDelegate(DoBind), new object[] { grid }
  );
}

private void DoBind(IMyGrid grid)
{
  grid.Bind(); // Expensive operation
}

private void RefreshComplete()
{
  IAsyncResult grid1Asynch = InvokeBind(grid1);
  IAsyncResult grid2Asynch = InvokeBind(grid2);
  IAsyncResult grid3Asynch = InvokeBind(grid2);
  IAsyncResult grid4Asynch = InvokeBind(grid3);
  IAsyncResult grid5Asynch = InvokeBind(grid4);
  IAsyncResult grid6Asynch = InvokeBind(grid5);
}

Now I could spin off a separate thread and keep checking to see if the IAsynchResults have completed and depending on which one completes I could re-enable the Tab control that the grid is contained in. Is there a better way of doing this?

Any direct manipulation of a Control (instance which includes all standard and extension WinForms controls) has to be done on the thread on which that control was created. The Windows GUI is not thread safe, in fact each window created (and most controls will create at least one) has thread affinity.

Normally Control.BeginInvoke is used by other threads to perform some action on the GUI thread so properties can be read or set correctly.

You can certainly spin up work items in the thread pool to get data with which you will later populate the grids, but the actual configuration and population the grids (including data binding) has to be done on the GUI thread. If it takes time to get the data this is probably a good idea (but doing them all together might be slower—due to contention at the data source—than all at once) because you can get the GUI responsive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM