C# WinForms Control.BeginInvoke异步回调

C# WinForms Control.BeginInvoke异步回调,c#,asynchronous,controls,callback,C#,Asynchronous,Controls,Callback,我有许多Janus网格控件需要在应用程序启动时填充 我希望将这些网格加载到不同的线程上,以加快启动时间和刷新这些网格所需的时间。每个网格位于单独的选项卡上。理想情况下,我希望在每个网格上使用Control.BeginInvoke,并在网格加载时启用选项卡 我知道对于委托,在使用BeginInvoke时可以执行异步回调,因此我可以在异步回调中启用选项卡,但是在使用Control.BeginInvoke时,这是不可能的。有没有一种方法可以使用Control.BeginInvoke或更好的解决方案进行

我有许多Janus网格控件需要在应用程序启动时填充

我希望将这些网格加载到不同的线程上,以加快启动时间和刷新这些网格所需的时间。每个网格位于单独的选项卡上。理想情况下,我希望在每个网格上使用Control.BeginInvoke,并在网格加载时启用选项卡

我知道对于委托,在使用BeginInvoke时可以执行异步回调,因此我可以在异步回调中启用选项卡,但是在使用Control.BeginInvoke时,这是不可能的。有没有一种方法可以使用Control.BeginInvoke或更好的解决方案进行异步回调

到目前为止,我已经:

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);
}

现在,我可以分离出一个单独的线程,并继续检查IAsynchResults是否已完成,根据哪个线程完成,我可以重新启用包含网格的选项卡控件。有更好的方法吗?

控件的任何直接操作(包括所有标准和扩展WinForms控件的实例)都必须在创建该控件的线程上进行。Windows GUI不是线程安全的,事实上创建的每个窗口(大多数控件将至少创建一个)都具有线程关联性

通常情况下,其他线程使用
Control.BeginInvoke
在GUI线程上执行某些操作,以便正确读取或设置属性


当然,您可以在线程池中启动工作项以获取数据,稍后将使用这些数据填充网格,但是网格的实际配置和填充(包括数据绑定)必须在GUI线程上完成。如果需要时间来获取数据,这可能是一个好主意(但由于数据源上的争用,将所有数据一起执行可能比一次执行要慢),因为您可以使GUI响应更快。

在填充之前和之后使用
SuspendLayout()
resumeloayout(false)
,这样网格就不会被直接状态所覆盖。