Using MethodImplAttribute


It is possible to synchronize an entire method by using the MethodImplAttribute attribute. This approach can be used as an alternative to the lock statement in cases in which the entire contents of a method are to be locked. MethodImplAttribute is defined within the System.Runtime.CompilerServices namespace. The constructor that applies to synchronization is shown here:

 public MethodImplAttribute(MethodImplOptions opt)

Here, opt specifies the implementation attribute. To synchronize a method, specify MethodImplOptions.Synchronized. This attribute causes the entire method to be locked on the instance (that is, via this).

Here is a rewrite of the TickTock class that uses MethodImplAttribute to provide synchronization:

 // Use MethodImplAttribute to synchronize a method. using System; using System.Threading; using System.Runtime.CompilerServices; // Rewrite of TickTock to use MethodImplOptions.Synchronized. class TickTock {   /* The following attribute synchronizes the entire      tick() method. */   [MethodImplAttribute(MethodImplOptions.Synchronized)]   public void tick(bool running) {     if(!running) { // stop the clock       Monitor.Pulse(this); // notify any waiting threads       return;     }     Console.Write("Tick ");     Monitor.Pulse(this); // let tock() run     Monitor.Wait(this); // wait for tock() to complete   }   /* The following attribute synchronizes the entire      tock() method. */   [MethodImplAttribute(MethodImplOptions.Synchronized)]   public void tock(bool running) {     if(!running) { // stop the clock       Monitor.Pulse(this); // notify any waiting threads       return;     }     Console.WriteLine("Tock");     Monitor.Pulse(this); // let tick() run     Monitor.Wait(this); // wait for tick() to complete   } } class MyThread {   public Thread thrd;   TickTock ttOb;   // Construct a new thread.   public MyThread(string name, TickTock tt) {     thrd = new Thread(this.run);     ttOb = tt;     thrd.Name = name;     thrd.Start();   }   // Begin execution of new thread.   void run() {     if(thrd.Name == "Tick") {       for(int i=0; i<5; i++) ttOb.tick(true);       ttOb.tick(false);     }     else {       for(int i=0; i<5; i++) ttOb.tock(true);       ttOb.tock(false);     }   } } class TickingClock {   public static void Main() {     TickTock tt = new TickTock();     MyThread mt1 = new MyThread("Tick", tt);     MyThread mt2 = new MyThread("Tock", tt);     mt1.thrd.Join();     mt2.thrd.Join();     Console.WriteLine("Clock Stopped");   } }

The proper Tick Tock output is the same as before.

As long as the method being synchronized is not defined by a public class, then whether you use lock or MethodImplAttribute is yours to choose. Both produce the same results. Since lock is a keyword built into C#, that is the approach that the examples in this book will use. However, for public classes, you should use lock, locking on a private object to avoid potential problems caused by code beyond your control.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net