WinForm中跨线程修改界面控件

在WinForm项目中,我们通常会采用界面逻辑分离,由逻辑线程触发的对界面控件的操作,会因为跨线程导致各种问题,那么是否有一种通用操作,来解决我们在日常开发遇到的这种问题呢?

我所遇到的具体问题如下:当前有两条线程,线程1为UI线程,所有UI都在此线程中初始化,线程2为消息线程,通常情况下线程2是阻塞的,但是我们必须要在线程2中触发对界面的操作,比如登录结束后,收到login_res,需要隐藏登录界面并且展示主界面。当我在线程2中操纵界面显示的时候,会由于线程2自己的阻塞导致主界面加载到一半便会卡死。此时做线程输出,会发现对界面的操作一直是在线程2上的,即使我强制调用界面的refresh方法刷新界面,也会由于线程的阻塞导致后续界面一直是卡死状态

理所当然的,我们会想到Contral的Invoke。那么接下来,结合我的框架聊一下我的设计。

我的架构采用界面-界面控制-逻辑三层,其中界面控制层提供一系列的委托,提供给逻辑层调用

首先由于我使用的界面并不多,这里我们以登录界面和创角界面来做展示,运行逻辑为:程序开始时创建登录界面,玩家输入账号密码,点击确认后向服务器发送login_req,当服务器检测到没有此账号,便会在login_res中携带一个标识,当消息线程读取到此标识后,会打开创角界面。

下面是登录界面的构造函数

	public LoginForm()//登录界面,于程序开始时初始化
    {
        InitializeComponent();//界面初始化
        if (MyClient.SFlag == 1)//对与服务器的连接状体做输出
        {
            this.label_connect.Text = "连接状态:已连接";
        }
        Control.CheckForIllegalCrossThreadCalls = false;//允许其他线程操作界面
        //在这里初始化界面,此时是在UI线程中初始化
        GameFrame.formContral.hideLogin = new FormDelegate(hideLogin);
        CreatForm cf = new CreatForm();
        //这一步很关键,需要调用界面Show方法,才可以在当前线程创建界面句柄
        cf.Show();
        cf.Hide();
    }

下面是创角界面的构造函数

      public CreatForm()
     {
        InitializeComponent();//界面初始化
        Control.CheckForIllegalCrossThreadCalls = false;//允许跨线程访问(可以不加)
        GameFrame.formContral.showCreate = new FormDelegate(showForm);//将构该界面中对界面的操作封装成方法交给委托
     }

下面是创角界面在消息线程上被调用的方法

public void showForm()
    {
        OpeMainFormControl(delegate ()
        {
            this.Show();
        });
    }
    private void OpeMainFormControl(Action action)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(action); //返回主线程(创建控件的线程)
        }
        else
        {
            action();
        }
    }
}

首先,这里需要用到控件的Invoke,它可以将对控件的操作委托回控件创建的线程进行操作,这样就解决了跨线程调用的线程安全问题,并且,这个方法是在消息线程中调用,消息线程总是阻塞的。
这里有一点需要特别注意,如果在界面创建的线程上没有调用界面的Show方法,那么是不会在改线程上创建界面的句柄,那么"this.InvokeRequired"的值为false,此时无法invoke!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值