您的位置:首页 > 其它

不同线程访问同一控件导致的不安全错误解决办法

2019-03-07 10:47 477 查看

WinForm不同线程访问同一控件导致的不安全错误解决办法

  • 解决方案分析
  • 错误原因分析

    造成这一错误的原因通常是非创建该控件的线程操作了这个控件,比如主线程创建了窗口A,分线程要关掉窗口A。因为程序并不能确定主线程是不是在操作这个窗口,所以盲目的关闭这个窗口会造成不可预料的错误!(当然,只要你逻辑清楚是不会出错的,但是编译器还是要强制进行安全检查)

    解决方案

    对于这个问题,最好的解决方案是通过创建该控件的进程操作这个控件,那么怎么在分线程中找到创建该控件的线程呢?答案是使用代理(委托),把分线程不能操作的方法包成代理方法,让分线程中被操作的控件执行这个代理就可以了。

    代码实现

    场景假设

    假设通过FormA去创建FormB,之后在通过新线程去关闭FormB

    FormA去创建FormB

    private void button1_Click(object sender, EventArgs e)
    {
        FormB fb = new FormB();
        fb.ShowDialog();
    }

    FormA创建新线程管理FormB

    private void button1_Click(object sender, EventArgs e)
    {
        //其中closeFormMethod为你要管理控件的方法;
        Thread th = new Thread( new ThreadStart(closeFormMethod) );
        th.Start();

        FormB fb = new FormB();
        fb.ShowDialog();
    }

    分线程中创建代理,并用代理去执行分线程中不能执行的方法

    private delegate void HideFrom();
    private void closeFormMethod()
    {
        //延时3S是为了保证窗口B确确实实被创建了
        Thread.Sleep(3000);
        HideFrom hideFrom = new HideFrom(fb.Close);
        fb.Invoke(hideFrom);
    }

    解决方案分析

    这个代理方法并不是真正由分线程执行的,而是由创建控件的线程执行的,当控件调用invoke方法的时候,会通过控件的控件树找到创建这个控件的父控件,从而找到父控件中创建这个控件的线程,并由这个线程调用代理方法。从而做到线程安全。

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: 
    相关文章推荐