我在学习线程池和事件时遇到一个问题,具体如下,首先在线程池中线程处理事件,触发事件是在windows窗体前台,运行和调试没有任何异常,可是程序运行陷入类似于无限循环的情况,简化代码如下
求指教 
控制器类中声明的委托和时间
class Controller
{
        public delegate void PrintEventHandler(object sender, PrintEventArgs e);
        public event PrintEventHandler PrintEvent;        protected virtual void OnPrint(PrintEventArgs e)
        {
            if (PrintEvent == null) return;
            PrintEvent(this, e);
        }        private void StartJob(object state)
        {
               PrintEventArgs e = new PrintEventArgs(str);
               OnPrint(e);
        }        public string RunJob()
        {//线程池中线程触发事件
        n=10;
        while(n-->0)
        {
                 ThreadPool.QueueUserWorkItem(StartJob, job);
        }
}
事件参数类
public class PrintEventArgs : EventArgs
    {
        string output = "";
        public PrintEventArgs(string s)
        {
            this.output = s;
        }
        public string Output
        {
            set { output = value; }
            get { return output; }
        }
    }
窗口类
public partial class Form1 : Form
{
        private Controller Pri = new Controller();
        private void PrintMsg(object sender, PrintEventArgs e)
        {//填充文本框Output
            if (txtOutput.InvokeRequired)
            {
                Controller.PrintEventHandler call = new Controller.PrintEventHandler(PrintMsg);
                txtOutput.Invoke(call,sender,e );
            }
            else
                txtOutput.Text += e.Output;
        }
       private void btnPri_Click(object sender, EventArgs e)
        { 按钮触发时间后撤销时间
            txtOutput.Text = string.Empty;
            Pri.PrintEvent += this.PrintMsg;
            txtOutput.Text += Pri.RunJob();
            //Pri.PrintEvent -= this.PrintMsg;
        }
}
}

解决方案 »

  1.   

    在每个方法的开头,加上log,看它的执行顺序就能发现问题。
      

  2.   

    -->
    private void btnPri_Click(object sender, EventArgs e)

        //按钮触发时间后撤销时间
        Pri.PrintEvent -= this.PrintMsg;
        txtOutput.Text = string.Empty;
        Pri.PrintEvent += this.PrintMsg;
        txtOutput.Text += Pri.RunJob();
    }
      

  3.   

    另外提一句,我把PrintMsg的方法体改为
    MessageBox.Show(e.Output);
    程序是没有问题的,消息框会正常出来,文本框也会正常显示文本
      

  4.   

    control.invoke()用control.begininvoke()代替试试,两者的实质差不多,只不过调用时机不同,前者可能要等待很长时间甚至陷入死循环,后者调用后,方法立即在主线程执行,而不需要等待调用线程结束后才开始