读书人

事件定义中为何出现 Lock关键字?该如

发布时间: 2012-03-31 13:13:26 作者: rapoo

事件定义中为何出现 Lock关键字?

C# code
namespace WrapTwoInterfaceEvents{    using System;    public interface IDrawingObject    {        // Raise this event before drawing        // the object.        event EventHandler OnDraw;    }    public interface IShape    {        // Raise this event after drawing        // the shape.        event EventHandler OnDraw;    }    // Base class event publisher inherits two    // interfaces, each with an OnDraw event    public class Shape : IDrawingObject, IShape    {        // Create an event for each interface event        event EventHandler PreDrawEvent;        event EventHandler PostDrawEvent;        object objectLock = new Object();        // Explicit interface implementation required.        // Associate IDrawingObject's event with        // PreDrawEvent        event EventHandler IDrawingObject.OnDraw        {            add            {                lock (objectLock)                {                    PreDrawEvent += value;                }            }            remove            {                lock (objectLock)                {                    PreDrawEvent -= value;                }            }        }        // Explicit interface implementation required.        // Associate IShape's event with        // PostDrawEvent        event EventHandler IShape.OnDraw        {            add            {                lock (objectLock)                {                    PostDrawEvent += value;                }            }            remove            {                lock (objectLock)                {                    PostDrawEvent -= value;                }            }        }        // For the sake of simplicity this one method        // implements both interfaces.         public void Draw()        {            // Raise IDrawingObject's event before the object is drawn.            EventHandler handler = PreDrawEvent;            if (handler != null)            {                handler(this, new EventArgs());            }            Console.WriteLine("Drawing a shape.");            // RaiseIShape's event after the object is drawn.            handler = PostDrawEvent;            if (handler != null)            {                handler(this, new EventArgs());            }        }    }    public class Subscriber1    {        // References the shape object as an IDrawingObject        public Subscriber1(Shape shape)        {            IDrawingObject d = (IDrawingObject)shape;            d.OnDraw += new EventHandler(d_OnDraw);        }        void d_OnDraw(object sender, EventArgs e)        {            Console.WriteLine("Sub1 receives the IDrawingObject event.");        }    }    // References the shape object as an IShape    public class Subscriber2    {        public Subscriber2(Shape shape)        {            IShape d = (IShape)shape;            d.OnDraw += new EventHandler(d_OnDraw);        }        void d_OnDraw(object sender, EventArgs e)        {            Console.WriteLine("Sub2 receives the IShape event.");        }    }    public class Program    {        static void Main(string[] args)        {            Shape shape = new Shape();            Subscriber1 sub = new Subscriber1(shape);            Subscriber2 sub2 = new Subscriber2(shape);            shape.Draw();            // Keep the console window open in debug mode.            System.Console.WriteLine("Press any key to exit.");            System.Console.ReadKey();        }    }}/* Output:    Sub1 receives the IDrawingObject event.    Drawing a shape.    Sub2 receives the IShape event.*/

上面一段是MSDN的源码,关于interface + event的,
让我不明白的是:下面,这里为何要用lock关键字, 还有定义了一个object。
C# code
object objectLock = new Object();        // Explicit interface implementation required.        // Associate IDrawingObject's event with        // PreDrawEvent        event EventHandler IDrawingObject.OnDraw        {            add            {                lock (objectLock)                {                    PreDrawEvent += value;                }            }            remove            {                lock (objectLock)                {                    PreDrawEvent -= value;                }            }        } 



我自己模仿的时候如下:没用lock关键字和 那个object,也可以正常运行
C# code
interface myin    {        event mylele myevent;    }class zi : fu,myin    {        //event mylele shijian        //{        //    add { this.myevfu += value; }        //    remove { this.myevfu -= value; }        //}        event mylele _mye;        event mylele myin.myevent        {            add            {                //ock (objectLock)                //{                _mye += value;                //}            }            remove            {                _mye -= value;            }        }        public void shuohua()        {            Console.WriteLine("shuohua:");            if(_mye!=null)            {                _mye(this);            }        }    }

我网上查资料的时候,发现lock关键字的相关信息都是在多线程的时候用的,这里涉及到多线程吗?为何这里要加这个,像我上面的代码那样不加,以后会不会造成什么潜在的漏洞,谢谢大神们~!!

[解决办法]
这说起来就话长了,
先说 a+=1,这个操作在多线程中是不安全的,楼主,你理解了这个,就什么都好说了。
a+=1其实是两步操作 先把a的值取出来,然后+1,然后再写回a里面去
假设初始a = 0;
线程1 a+=1.线程2 a+=1,
线程1,先把a的值取出来,+1,这时切换到了线程2.线程2把a的值取出来,+1,然后线程1,线程2分别把值写回去。最后的结果就是a == 1,很明显这和你预期的 a == 2 是不相符的。
[解决办法]
探讨

引用:

这说起来就话长了,
先说 a+=1,这个操作在多线程中是不安全的,楼主,你理解了这个,就什么都好说了。
a+=1其实是两步操作 先把a的值取出来,然后+1,然后再写回a里面去
假设初始a = 0;
线程1 a+=1.线程2 a+=1,
线程1,先把a的值取出来,+1,这时切换到了线程2.线程2把a的值取出来,+1,然后线程1,线程2分别……

读书人网 >C#

热点推荐