2个线程作不同是动作,但是有一个相同的动作就是往窗体的text文本控件里添加各自操作的日志,我开一个线程就没有任何问题,我开2个线程就会报“未将对象引用设置到对象的实例。”代码如下是.net开发的windows应用程序
窗体load事件中启动线程的代码:  private void Form1_Load(object sender, EventArgs e)
        {
           threadGet1 = new Thread(new ThreadStart(doGetFromXml1));          
                        threadGet2 = new Thread(new ThreadStart(doGetFromXml2));            threadGet1.Start();
            threadGet2.Start();
           
            
        }两个线程的代码:
 public void doGetFromXml1()
         {
             
            
            while (true)
            {
                System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
                richTextBox1.Text = "aaaa\r\n";
            }
         } public void doGetFromXml2()
         {
             
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            while (true)
            {
                
                richTextBox1.Text = "oooo\r\n"; //运行到这里就会报“未将对象引用设置到对象的实例。”的错误
            }
         }
要如何解决呢?

解决方案 »

  1.   

    是哪个对象是null?richTextBox1么,还有,同事操作richTextBox1,最好加一个lock
    类里边加一个成员object sysobj=new Object();
    lock(sysobj)
    {
     richTextBox1.Text = "oooo\r\n"; 
    }
      

  2.   

    最好不要用CheckForIllegalCrossThreadCalls ,而是用invoke方法到UI线程执行
      
    *****************************************************************************
    欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码) http://feiyun0112.cnblogs.com/
      

  3.   

    安照1,2楼的方法改就好了using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Threading;
    namespace WindowsApplication2
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private void Form1_Load(object sender, EventArgs e)
            {
                Thread threadGet1, threadGet2;            threadGet1 = new Thread(new ThreadStart(doGetFromXml1));            threadGet2 = new Thread(new ThreadStart(doGetFromXml2));            threadGet1.Start();
                threadGet2.Start();        }        object sysobj = new Object();        public void doGetFromXml1()
            {            while (true)
                {
                    lock (sysobj)
                    {
                        ShowMessage("oooo\r\n");
                    }
                }
            }        public void doGetFromXml2()
            {            while (true)
                {                lock (sysobj)
                    {
                        ShowMessage("aaaa\r\n");
                    }
                }        }        delegate void ShowMess(String s);
            void ShowMessage(string s)
            {
                if (this.richTextBox1.InvokeRequired == true)
                {
                    this.richTextBox1.Invoke(new ShowMess(ShowMessage),new object[]{s});
                }
                else
                {
                    this.richTextBox1.Text = s;
                }
            }
        }
    }
      

  4.   

    richTextBox1//两个线程访问了同一对象,要互斥,还有,最好不要在线程中直接操作界面;慎用:CheckForIllegalCrossThreadCalls 
      

  5.   

    我觉的应该是你2个线程都同时在使用一个richTextBox1控件,而且是无限的在使用这样肯定会报上面那个错的,加锁可以处理此类问题,用线程的挂起(Suspend())跟重启(Resume())来灵活的控制线程比较方便点,用完了就让它挂起这样就不会一直占用资源,要用的时候在启动,不过这样用最好还是加上一个判断条件就是判断该线程当前处于一个什么状态,可以这样判断:
             ThreadState ts=线程名.ThreadState;
                    if (ts == ThreadState.Unstarted || ts == ThreadState.Stopped)
                    {
                      线程名.Start();
                    }
             else
                    {
                      线程名.Resume();
                    }个人的建议,最近也在捣鼓多线程这个东东,也比较迷茫。
      

  6.   

    自定义的两个工作线程与用户界面是不同的线程,所以会有一些意想不到的错误发生。即使只有一个工作线程doGetFromXml1,也是有可能会发生错误的。2楼是正解,用Invoke到UI线程去更新。
      

  7.   


    正解,谢谢!
    也谢谢feiyun0112.结贴了