确保子控件的主UI线程创建线程、控件、UI

2023-09-04 06:13:34 作者:再賤就再見

我修改现有的WinForms项目。该项目具有用户控件。 这个用户控件具有从在不同的线程程序的另一部分设置数据集变量

I'm modifying existing WinForms project. The project has UserControl. This UserControl has DataSet variable which is set from another part of the program in different thread.

我想要做的就是动态地添加其他控件,该控件根据数据集。

What I want to do is to dynamically add another controls to this control depending on the DataSet.

因此​​,加载数据集后,我打电话RefreshChildControl功能,并尝试添加我的新ChildUserControls到FlowLayoutPanel的。而这正是问题的开始:)。我得到了跨线程操作无效:控制'ChildUserControl'从一个线程比它在创建线程的其他访问异常。我想如果(this.InvokeRequired)使用和调用此方法,但它并不能帮助。 InvokeRequired上的MyUserControl是假的。

So, after DataSet is loaded, I'm calling RefreshChildControl function and trying to add my new ChildUserControls to flowLayoutPanel. And that's where the problems begin:). I get the "Cross-thread operation not valid: Control 'ChildUserControl' accessed from a thread other than the thread it was created on" exception. I tried to use if(this.InvokeRequired) and Invoke this method, but it does not help. InvokeRequired on MyUserControl is false.

那么,有没有执行这样的任务什么好的办法?还是我失去了一些重要的东西?

So, is there any good way of performing such task? Or am I missing something important?

编辑:

我试图跳过InvokeRequired测试并调用this.FindForm()调用此方法。我有调用或BeginInvoke不能调用控件上,直到窗口句柄已创建。例外。而且,顺便说一下,当我与此控件都打开另一种形式的罚款。

I tried to skip InvokeRequired test and just call this.FindForm().Invoke on this method. I've got "Invoke or BeginInvoke cannot be called on a control until the window handle has been created." exception. And, by the way, when I open another form with this control everything worked fine.

推荐答案

第一。最简单的解决方案是执行调用每次。没有什么大不了的事情。 其次,使用的SynchronizationContext。

First. The simplest solution is to perform Invoke everytime. Nothing bad will happen. Second, use SynchronizationContext.

using System.Threading;
public class YourForm
{
    SynchronizationContext sync;
    public YourForm()
    {
        sync = SynchronizationContext.Current;
        // Any time you need to update controls, call it like this:
        sync.Send(UpdateControls);
    }

    public void UpdateControls()
    {
        // Access your controls.
    }
}

的SynchronizationContext将管理所有线程问题为您服务。它会检查,无论你来自相同或来自其它线程中调用。如果来自同它只会立即执行你的code。否则,将通过形式的消息循环做调用。

SynchronizationContext will manage all threading issues for you. It checks, whether you call from the same or from the other thread. If from same it will just immediately execute your code. Otherwise it will do Invoke through form's message loop.