事件定义中为何出现 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 是不相符的。
[解决办法]