gpt4 book ai didi

c# - WinForms Control.BeginInvoke 异步回调

转载 作者:行者123 更新时间:2023-11-30 18:09:36 24 4
gpt4 key购买 nike

我有许多需要在应用程序启动时填充的 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 线程上执行一些操作,以便正确读取或设置属性。

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

关于c# - WinForms Control.BeginInvoke 异步回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2354800/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com