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

c#中多线程的问题

郁闷的是,在点击停止后中奖结果竟然与上面六个label里显示的字符串不一样。。。

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 摇奖机
{
    public partial class Form1 : Form
    {
        
        public Form1()
        {
            
            InitializeComponent();
        }
        Thread n1;


        bool isStart = false;
        private void btnControl_Click(object sender, EventArgs e)
        {
            
            if (isStart == false)
            {
                n1 = new Thread(NumberChange);

                n1.Start();

                isStart = true;
                btnControl.Text = "结束";
                
            }
            else
            {

                n1.Abort();


                isStart = false;
                btnControl.Text = "开始";
                if (n1.ThreadState == ThreadState.Aborted)
                {
                    
                    labResult.Text = "中奖结果:" + labnum1.Text + labnum2.Text + labnum3.Text + labnum4.Text + labnum5.Text + labnum6.Text;
                }
            }
        }

        void end()
        {
            n1.Abort();


        }
        private void NumberChange()
        {
            
            Random ran = new Random();
            delegateSafeThread = SetLabText;

            while (true)
            {
                labnum1.Invoke(delegateSafeThread, ran, labnum1);
                labnum2.Invoke(delegateSafeThread, ran, labnum2);
                labnum3.Invoke(delegateSafeThread, ran, labnum3);
                labnum4.Invoke(delegateSafeThread, ran, labnum4);
                labnum5.Invoke(delegateSafeThread, ran, labnum5);
                labnum6.Invoke(delegateSafeThread, ran, labnum6);
            }
            
        }
        NumberChangeDelegate delegateSafeThread;
        private void SetLabText(Random ran,Label lab )
        {
           
                lab.Text = ran.Next(10).ToString();

                
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (isStart)
            {
                e.Cancel = true;
                MessageBox.Show("关闭前请先停止摇奖");
            }
        }
        
    }
    delegate void NumberChangeDelegate(Random ran, Label lab);
    
}




------解决方案--------------------
发现一个新的问题,你这里线程中使用了Invoke,出现了线程的回调,也就是说,Invoke内部执行的方法是必须在btnControl_Click方法结束后才会执行,那么你的改变将无法同步也是那个造成的。
方法有二:
一、直接修改Label的Text属性,设置CheckForIllegalCrossThreadCalls = false;

二、用中间变量存储,让改变先即时修改这些共享的变量。
------解决方案--------------------
C# code
using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        Thread n1;
        bool isStart = false;
        NumberChangeDelegate delegateSafeThread;
        delegate void NumberChangeDelegate(Random ran, Label lab);

        private void btnControl_Click(object sender, EventArgs e)
        {
            if (isStart == false)
            {
                n1 = new Thread(NumberChange);
                n1.Start();
                isStart = true;
                btnControl.Text = "结束";
            }
            else
            {
                isStart = false;
                btnControl.Text = "开始";
            }
        }

        private void NumberChange()
        {
            Random ran = new Random();
            delegateSafeThread = SetLabText;

            while (isStart)