c#多线程打开和关闭新的界面

最近在一个项目中,由于调用的方法需要等待较长时间才有返回值,这就造成界面假死的现象,在用户体验方面
很不友好。为此我新增了一个UI作为等待界面,在调用该方法时在新线程里打开这个UI,显示等待界面,方法执行完关闭该UI。原理很简单,实现的时候却遇到不少问题。
我写了一个简单的测试程序,主界面为Form1,等待界面为Wait,使用timer1定时模拟等待时间。
测试一:新建线程为th_showwait,代码如下:


Thread th_showwait;
///<summary>
///使用控件模拟调用方法
///</summary>
private void button1_Click(object sender, EventArgs e)
{
       ThreadStart();
 }
 /// <summary>
/// 啟動等待界面線程,模拟2s后线程关闭
 /// </summary>
	public void ThreadStart()
	{
    	 try
      	{
       		th_showwait = new Thread(ShowForm);
       		th_showwait.IsBackground = true;
       		th_showwait.Start();
       		Thread.Sleep(2000);
       		ThreadAbort();
       	}
       catch (Exception ex)
      {
      }
	}
 /// <summary>
/// 打開等待界面
/// </summary>
private void ShowForm()
{
      try
      {
           wait = new Wait();
           wait.ShowDialog();
       }
       catch (Exception ex)
       {                
       }
}		

结果如下:
在这里插入图片描述
开始运行没什么问题,线程和界面能正常显示,但是运行一段时间后,出现了“无法启动正在终止的线程”,意味着线程启动失败了,究其原因还是线程终止的机制,About()是非正常结束,即使使用Join()也无济于事,甚至让界面假死,界面显示不了等待图片,客户简直不能忍受。。。
测试二:没方法,线程频繁启停的方法既不靠谱又消耗系统资源,我只能尝试不用线程启停的方式打开等待界面,这时想到了用全局变量去做,这里有点要注意,开启不能用ShowDialog(),要用Show(),线程运行到ShowDialog()会停止往下执行,直到界面关闭,界面关闭不能用Close(),因为Close()执行了close和dispose方法,这就导致界面被释放,下次打开会出现失败,报错不能访问已经释放的资源,这里使用Hide()隐藏。调试好的代码如下

        Wait wait = new Wait();
        private int fun_code;
        Thread th_funcode;
        ///
        ///使用定时器模拟关闭信号
        ///
        private void button1_Click(object sender, EventArgs e)
        {
            fun_code = 1;
            timer1.Interval = 2000;
            timer1.Start();
        }
        
        private void timer1_Tick(object sender, EventArgs e)
        {
            fun_code = -1;
            timer1.Stop();
        }
        
		 private void Form1_Load(object sender, EventArgs e)
        {
            th_funcode = new Thread(ShowAndClose);
            th_funcode.IsBackground = true;
            th_funcode.Start();
        }
        
         private void ShowAndClose()
        {
            while (true)
            {
                try
                {
                    this.Invoke((MethodInvoker)delegate
                    {
                        //wait2 = new Wait();
                    if (fun_code==1)
                    {
                        fun_code = 0;
                        wait2.Show(this);
                        
                    }
                    if (fun_code==-1)
                    {
                        wait2.Hide();
                        fun_code = 0;
                        
                    }
                    });
                }
                catch (Exception ex)
                {

                    //throw;
                }

            }
        }

自此,程序完美运行。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值