VS2008
.Net3.5
C# WinForm界面上,只有一个button和一个textBox
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;
using System.Collections;namespace CSharp多线程传参
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Form.CheckForIllegalCrossThreadCalls = false;
        }        private ArrayList arr = new ArrayList();        private void button1_Click(object sender, EventArgs e)
        {
            arr.Add(1);
            Thread newT1 = new Thread(this.SetLength);//让arr[0]不断++,间隔是
            Thread newT2 = new Thread(this.GetLength);//显示arr[0]的值
            newT1.Start();
            Thread.Sleep(200);
            newT2.Start();
        }        private void FormMove( Form form )
        {
            //form.Location.X += 50;
            Thread.CurrentThread.Abort();
        }        private void SetLength()
        {
            //彻底锁住arr
            lock (this.arr)
            {
                while (true)
                {
                    this.arr[0] = (int)this.arr[0] + 1;
                    Thread.Sleep(300);
                }
            }
        }        private void GetLength( )
        {
            while( true )
            {
                Thread.Sleep(50);
                lock (this.textBox1)
                {
                    this.textBox1.Text = this.arr[0].ToString();
                    this.arr[0] = (int)this.arr[0] - 1;
                }
            }
        }    }
}1。点按钮,执行button1_Click方法。2。newT1线程先执行,彻底锁定 arr,然后让arr[0]++。3。newT2线程在newT1执行了200毫秒后才执行,显示arr[0]的值,并且让arr[0]--。
按理说,newT1里已经彻底lock了arr,为什么newT2还能显示它的值,甚至能修改?

解决方案 »

  1.   

    lock (this.textBox1)--》 应该改成 lock (this.arr)
      

  2.   

    lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。线程处理(C# 编程指南) 这节讨论了线程处理。lock 调用块开始位置的 Enter 和块结束位置的 Exit。通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:    *      如果实例可以被公共访问,将出现 lock (this) 问题。
        *      如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
        *      由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock(“myLock”) 问题。最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。
      

  3.   

    当多线程公用一个对象时,也会出现和公用代码类似的问题,这种问题就不应该使用C# lock关键字了,这里需要用到System.Threading中的一个类Monitor,我们可以称之为监视器,Monitor提供了使线程共享资源的方案。Monitor类可以锁定一个对象,一个线程只有得到这把锁才可以对该对象进行操作。对象锁机制保证了在可能引起混乱的情况下一个时刻只有一个线程可以访问这个对象。 Monitor必须和一个具体的对象相关联,但是由于它是一个静态的类,所以不能使用它来定义对象,而且它的所有方法都是静态的,不能使用对象来引用。