using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;namespace Test
{
    delegate void SetMatchCollectionCallback(System.Text.RegularExpressions.MatchCollection mcT);
    public delegate void JobCompleteHandle(System.Text.RegularExpressions.MatchCollection e);
    public delegate void BusyStatusChangedHandle(bool e);
    public partial class frmMain : Form
    {
        BGWorker bgwT;        public frmMain()
        {
            InitializeComponent();
        }        private void button1_Click(object sender, EventArgs e)
        {
                dlgOpenFile.ShowDialog();
        }        private void dlgOpenFile_FileOk(object sender, CancelEventArgs e)
        {
            string sT = string.Empty;
            using (System.IO.StreamReader srT = new System.IO.StreamReader(dlgOpenFile.FileName, Encoding.Default))
            {
                sT = srT.ReadToEnd();
            }
            bgwT = new BGWorker(ref sT, textBox1.Text, System.Text.RegularExpressions.RegexOptions.Multiline);
            bgwT.JobComplete += new JobCompleteHandle(bgwT_JobComplete);
            bgwT.StartJob();
        }        void bgwT_JobComplete(System.Text.RegularExpressions.MatchCollection e)
        {
            for (Int32 I = 0; I < e.Count; I++)
            {
                textBox2.AppendText(e[I].Value);//线程间操作无效: 从不是创建控件“textBox2”的线程访问它。
            }
        }
    }    public class BGWorker:System.Windows.Forms.Form//这行不管BGWorker是Form还是Control,结果一样出错
    {
        public event JobCompleteHandle JobComplete;
        private event JobCompleteHandle JobCompletePretreat;        string sToTreat;
        string sRegularString;
        System.Text.RegularExpressions.RegexOptions roOption;
        Control ctrT;        System.Threading.Thread thrT;        public BGWorker(ref string sToTreat, string sRegularString, System.Text.RegularExpressions.RegexOptions roOption)
        {
            this.sToTreat = sToTreat;
            this.sRegularString = sRegularString;
            this.roOption = roOption;
            ctrT = new Control();
            this.JobCompletePretreat += new JobCompleteHandle(BGWorker_JobCompletePretreat);
            thrT = new System.Threading.Thread(new System.Threading.ThreadStart(DoJob));
        }        //本来在这个事件里想要转到另一个线程去,结果不成功
        void BGWorker_JobCompletePretreat(System.Text.RegularExpressions.MatchCollection e)
        { 
            if (ctrT.InvokeRequired)//这个属性总是为false,奇怪!
            {
                SetMatchCollectionCallback smcT = new SetMatchCollectionCallback(BGWorker_JobCompletePretreat);
                this.Invoke(smcT, new object[] { e });
            }
            else
            {
                JobComplete(e);
            }
        }        public void StartJob()
        {
            thrT.Start();
        }        void DoJob()
        {
            System.Text.RegularExpressions.Regex reT = new System.Text.RegularExpressions.Regex(sRegularString, roOption);
            System.Text.RegularExpressions.MatchCollection mcT = reT.Matches(sToTreat);
            JobCompletePretreat(mcT);
        }
    }
}

解决方案 »

  1.   

    textBox2.AppendText(e[I].Value);//线程间操作无效: 从不是创建控件“textBox2”的线程访问它。 
    上面这句话要用异步调用,也就是委托,因为其它线程 与form线程存在冲突
      

  2.   

    //首先,在程序中声明一个delegate,并声明一个方法与delegate一致        delegate void AppendText(string text);
            private void AppendTextTask(string text)
            {
                textBox2.AppendText(text);
            }
    然后将 textBox2.AppendText(e[I].Value);改为如下代码        AppendText d=new AppendText(AppendTextTask);
            this.Invoke(d,new object[]{e[I].Value});
      

  3.   

    看了楼上几位的回复,让我有一个结论:
    就是说没有办法在上面程序里的BGWorker类里DoJob子线程完成后,就回到类的创建者的线程里再发出JobComplete事件了?
    我的目的就是这个啊。
      

  4.   

    同样的用invoke
    然后在委托里写你调用创建者线程的事件