日期:2014-05-18  浏览次数:20803 次

多线程中子线程没有结束前关闭窗口的问题
C# code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace MutiThread
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
           Control.CheckForIllegalCrossThreadCalls = false;
        }


        protected delegate void dShowPic(bool s);
        protected void ShowPic(bool s)
        {
            this.pictureBox1.Visible = s;
        }
        protected void RunShowPic()
        {
            bool s = this.pictureBox1.Visible;
            if (InvokeRequired)
            {
                this.Invoke(new dShowPic(ShowPic), !s);
            }
        }


        protected delegate void dSetVal(int val);
        protected void SetVal(int val)
        {
            progressBarX1.Value = val;
        }

        protected void RunSetVal()
        {
            Thread thp = new Thread(new ThreadStart(RunShowPic));
            thp.Start();
            int v = progressBarX1.Value;
            while (progressBarX1.Value < 100)
            {
                Thread.Sleep(100);
                if (InvokeRequired)
                {
                    lock (progressBarX1)
                    {
                        this.Invoke(new dSetVal(SetVal), v++);
                    }
                }
            }
            thp = new Thread(new ThreadStart(RunShowPic));
            thp.Start();
        }


        private void buttonX1_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(new ThreadStart(RunSetVal));
            th.Start();
            this.labelX1.Text = "正在执行中...";
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Application.Exit();
        }
    }
}





如果等待子进程结束,关闭窗口就没有问题,但是如果没有等待子程结束,就关闭窗口的就有问题

还有一个问题,如果反复点击 按钮一的话,进度条就会闪动,因为启动了多个子线程,这个问题又如何解决呢?

能不能根据子线程的ID强制中断或关闭?


代码中的labelX1,buttonX1如果没有安装dev控件,请把改为labelX,buttonX

------解决方案--------------------
在多线程的退出时,我是如下做的,效果还不错
1)主线程对所控制的子线程执行Sonthread.Join(),这样子线程都结束了,主线程才结束
2) 设法通知所有子线程,系统结束了,必须设置一个static bool _IsClose字段,对于有循环的子线程,通过判断该标记,可以立即退出循环,而不是死循环。
3)尽量避免使用thread.sleep(time), 而是用ManuResetEvent.WaitOne(time), 主线程结束时设法运行相应的ManuResetEvent.Set(),就可以立即中断waitOne()的等待操作。
4)要有耐心,原则上讲,所有子线程都可以通过以上措施自行关闭,最好不要使用Kill。
------解决方案--------------------
还有对于所有阻塞型的方法,如Socket.send()等,尽量转为非阻塞模式。
------解决方案--------------------
1. 子线程的方法加lock
2. 线程的isbackground设成true
------解决方案--------------------
将子线程设置为后台线程,将线程的IsBackground设置true;