有两条线程,工作线程实时获得出ID的值,主线程根据工作线程ID的值设置控件Lable.Text;
代码如下:
    public partial class Form1 : Form
{
        private void Form1_Load(object sender, EventArgs e)
        {
            test.SetLable += SetLable;
            Thread t = new Thread(new ThreadStart(test.ThreadRun));
            t.Start();
        }
        private void SetLable()
        {
            if(this.label1.InvokeRequired)
                this.Invoke(new SetLableEventHandler(SetLable));
            else                this.label1.Text=test.BackID().ToString();
        }
}delegate void SetLableEventHandler();
    static class test
    {
        static int ID = 0;
        static object LockObject = new object();
        public static event SetLableEventHandler SetLable;
        public static void ThreadRun()
        {
            lock (LockObject)
            {
                do
                {
                    ID++;
                    if (SetLable != null) SetLable();
                    //Thread.Sleep(100);
                } while (ID < 100000);
            }
        }
        public static int BackID()
        {
            lock (LockObject)
            {
                return ID;
            }
        }
    }以上静态类test的BackID和ThreadRun两个方法都用了lock锁定..这样马上就会出现死锁,如果不锁定
程序运行没有问题,但是理论上并不安全..因为程序原先的设计是基于组件(插件)方式的,主程序(主线程)并不知道插件内部实现,test是插件...所以改只能改test,,请问有什么好的方法..以上我认为是出现了交叉锁定引起死锁的...即this.Invoke里面也存在一个锁..

解决方案 »

  1.   

    将上面  test.ThreadRun方法改为
    public static void ThreadRun()
            {
                 do
                    {
                       lock (LockObject)
                        {
                            ID++;
                        }
                        if (SetLable != null) SetLable();
                        //Thread.Sleep(100);
                    } while (ID < 100000);
                }
            
      

  2.   

    int 类型可以不用lock,不会有安全问题。而且如果只是取值的话,也不需要去lock,因为取值不会破坏数据。
      

  3.   


      if(this.label1.InvokeRequired)
                    this.Invoke(new SetLableEventHandler(SetLable)); //把BackID的值作为参数传过去 
      

  4.   

    1楼的正解。lock (LockObject)
    {
        do
        {
            ID++;
            if (SetLable != null) SetLable();
            //Thread.Sleep(100);
         }while (ID < 100000);
    }
    你在已经锁的情况下又调用setlabel-> BackID()-> lock (LockObject)在这里死锁了。因为锁还未被释放。