线程中创建winform

1.情景

想对外提供一个类库,但是这个类库是一个ui类型的,这就涉及到一个问题,调用这个接口的线程可能不是主线程(ui线程),而如果操作和控制ui(一般是)必须在主线程的。这时候如何能保证任何线程调用该接口都能切换到主线程呢。这就需要设置这个接口,无论任何接口的调用,最终控制ui的时候都自动切换到主线程。

有个问题,子线程不能控制ui,但是能创建winform吗,实验确认可以,但是控制winform中的ui必须在主线程

2.代码

2.1 工程概述

目标:创建两个winform,form1,form2。尝试在from1中调用form2的接口。 

 

实验cace

情景form线程使用对象方式结果
form1 中主线程控制form2的控件主线程成功
form1中子线程控制form2的控件子线程form2直接调用失败
调用form2的setTextPost失败
form2.m_SyncContext成功

2.2 form1 代码

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 线程中创建winform
{
    public partial class Form1 : Form
    {
        Form2 form2;
        SynchronizationContext m_SyncContext = null;
        public Form1()
        {
            InitializeComponent();
            m_SyncContext = SynchronizationContext.Current;
        }

        //子线程创建form-间接SyncContext.Post
        private void button1_Click(object sender, EventArgs e)
        {
            Task t = new Task(()=> {
                form2 = new Form2();

                form2.ShowDialog();// 使用这个可以,因为焦点在From1中。
                //form2.Show();// 使用这个不可以,因为焦点不在From1中。
                {
                    //这里写入失败
                    //form2.myTextBox1.Text = "线程中写数据-form2";
                }
                {
                    //这里写入会失败-因为不在u线程
                    //textBox1.Text = "线程中写数据-form1";
                }
                {
                    form2.setTextPost("线程中写数据-form2");
                }
            });
            t.Start();
            {
                //这里
                textBox1.Text = "线程中写数据-form1";
            }
        }
        //-间接SyncContext.Post
        private void button2_Click(object sender, EventArgs e)
        {
            //线程中直接更新可以
            form2.setTextPost("线程中写数据-form2");
        }

        //主线程创建form
        private void button3_Click(object sender, EventArgs e)
        {
            form2 = new Form2();

            //form2.ShowDialog();
            form2.Show();
            {
                //这里写入成功-因为在主线程
                form2.myTextBox1.Text = "线程中写数据-form2";
            }
            {
                //这里写入会成功-因为在主线程
                textBox1.Text = "线程中写数据-form1";
            }

        }
        //主线程创建form -利用SyncContext.post调用函数可以

        private void button4_Click(object sender, EventArgs e)
        {
            form2 = new Form2();

            //form2.ShowDialog();
            
            form2.Show();
            SynchronizationContext SyncContext = form2.m_SyncContext;
            //这中可以
            SyncContext.Post(form2.setText, "线程中写数据-form2");
        }
    }
}

2.3 from2 代码

using System.Threading;
using System.Windows.Forms;

namespace 线程中创建winform
{
    public partial class Form2 : Form
    {
        public TextBox myTextBox1;
        public SynchronizationContext m_SyncContext = null;
        public Form2()
        {
            InitializeComponent();
            m_SyncContext = SynchronizationContext.Current;
            myTextBox1 = textBox1;
        }
        public void setText(object str) {
            textBox1.Text = str.ToString();
        }
        public void setTextPost(string str) {
            m_SyncContext.Post(setText, str);
        }
    }
}

3.运行效果

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值