主机是双核CPU,在执行多线程的时候,用了Monitor,但是发现不起什么作用,任务列表ql还是同时被线程访问,请问如何解决?下面是相关代码:public partial class nform : Form
    {
        Thread spiderThread;
        private delegate void runDelegate(string s);//修改对象文字
        queueList ql = new queueList();//任务列表
        tasklist tk = null;//单个任务对象
        public nform()
        {
            InitializeComponent();
        }        private void button1_Click(object sender, EventArgs e)
        {
            spiderThread = new Thread(new ThreadStart(runThread));
            spiderThread.Start();
        }        private void runThread()
        {
            lock (this)
            {
                initializeData();
                operLocalFile();
            }
        }
        //修改主输入文本窗口的文字
        private void changeText(string s)
        {
            msg.Text +=s;
        }
        //修改状态栏的文字
        private void changeStas(string s)
        {
            toolStripStatusLabel1.Text = s;
        }
        /// <summary>
        /// 将所有任务载入队列
        /// </summary>
        private void initializeData()
        {
            DataTable dt = DataOper.getDataset("select data_input,data_name,data_char from data_source_set where data_isoper=0").Tables[0];
            if (dt.Rows.Count > 0)
            {
                tasklist tkl = new tasklist("", "", "");
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    tkl.title = dt.Rows[i]["data_name"].ToString();
                    tkl.link = dt.Rows[i]["data_input"].ToString();
                    tkl.charset = dt.Rows[i]["data_char"].ToString();
                    ql.addtask(tkl);
                }
            }
        }
        /// <summary>
        /// 分析处理本地文件
        /// </summary>
        private void operLocalFile()
        {
            
            runDelegate d = new runDelegate(changeText);
            runDelegate d2 = new runDelegate(changeStas);
            while (ql.isQueueActive)
            {
                Monitor.Enter(ql);
                Thread.Sleep(100);
                getSingleWeb gsw = new getSingleWeb();
                tk = (tasklist)ql.getOneList();
                this.Invoke(d2, "正在处理:" + tk.title + ":" + tk.link);
                this.Invoke(d, "正在处理:" + tk.title + ":" + tk.link + "\n\r");
                gsw.singleWeb(tk.link, tk.charset);//将分析的代码存为本地文件
                this.Invoke(d2, tk.title + ":" + tk.link + "处理完毕");
                this.Invoke(d, tk.title + ":" + tk.link + "处理完毕\n\r");
                Monitor.Exit(ql);
            }
            
        }
    }qllist类 //要处理的任务队列
   public class queueList
    {
       private readonly Queue<tasklist> listQueue = new Queue<tasklist>();
       /// <summary>
       /// 向队列中添加一条记录
       /// </summary>
       /// <param name="tl"></param>
       public void addtask(tasklist tl)
       {
           lock (this)
           {
               listQueue.Enqueue(tl);
           }
       }
       /// <summary>
       /// 从队列中取出一条队列,并从队列中删除
       /// </summary>
       /// <returns></returns>
       public tasklist getOneList()
       {
           lock (this)
           {
               tasklist tl = null;
               tl = listQueue.Dequeue();
               return tl;
           }
       }
       /// <summary>
       /// 返回队列中是否还有任务
       /// </summary>
       public bool isQueueActive
       {
           get { return listQueue.Count > 0; }
       }
    }

解决方案 »

  1.   


    private void runThread()
            {
                lock (this)
                {
                    //initializeData();这里写错了,应该写到那个铵钮事件中
                    operLocalFile();
                }
            }
            private void button1_Click(object sender, EventArgs e)
            {
                initializeData();//这个写在这里
                spiderThread = new Thread(new ThreadStart(runThread));
                spiderThread.Start();
            }像下面这样子写,lock这个方法也不可以private void operLocalFile()
            {
                
                lock(this)
                {
                     runDelegate d = new runDelegate(changeText);
                runDelegate d2 = new runDelegate(changeStas);
                while (ql.isQueueActive)
                {
                    Monitor.Enter(ql);
                    Thread.Sleep(100);
                    getSingleWeb gsw = new getSingleWeb();
                    tk = (tasklist)ql.getOneList();
                    this.Invoke(d2, "正在处理:" + tk.title + ":" + tk.link);
                    this.Invoke(d, "正在处理:" + tk.title + ":" + tk.link + "\n\r");
                    gsw.singleWeb(tk.link, tk.charset);//将分析的代码存为本地文件
                    this.Invoke(d2, tk.title + ":" + tk.link + "处理完毕");
                    this.Invoke(d, tk.title + ":" + tk.link + "处理完毕\n\r");
                    Monitor.Exit(ql);
                }
                 }
                
            }