繁体   English   中英

WinForms Control.BeginInvoke异步回调

[英]WinForms Control.BeginInvoke asynchronous callback

我有一些需要在应用程序启动时填充的Janus网格控件。

我想在不同的线程上加载这些网格,以加快启动时间和刷新这些网格所需的时间。 每个网格都在一个单独的选项卡上。 理想情况下,我想在每个网格上使用Control.BeginInvoke,并且在网格加载上完成选项卡将变为启用状态。

我知道使用Delegates,你可以在使用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是否已经完成,并且根据哪一个完成,我可以重新启用包含网格的Tab控件。有更好的方法吗?

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

通常, Control.BeginInvoke被其他线程用于在GUI线程上执行某些操作,因此可以正确读取或设置属性。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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