C# WinForms Control.BeginInvoke异步回调
我有许多Janus网格控件需要在应用程序启动时填充 我希望将这些网格加载到不同的线程上,以加快启动时间和刷新这些网格所需的时间。每个网格位于单独的选项卡上。理想情况下,我希望在每个网格上使用Control.BeginInvoke,并在网格加载时启用选项卡 我知道对于委托,在使用BeginInvoke时可以执行异步回调,因此我可以在异步回调中启用选项卡,但是在使用Control.BeginInvoke时,这是不可能的。有没有一种方法可以使用Control.BeginInvoke或更好的解决方案进行异步回调 到目前为止,我已经:C# WinForms Control.BeginInvoke异步回调,c#,asynchronous,controls,callback,C#,Asynchronous,Controls,Callback,我有许多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)
,这样网格就不会被直接状态所覆盖。