home *** CD-ROM | disk | FTP | other *** search
- //==========================================================================
- // File: ThdRelStaticSample.cs
- //
- // Summary: Example shows how to use the attribute [ThreadStatic( )]
- // to make a static field be a Thread Relative Static.
- //
- // Note: If you compile this sample with the "/D:WITHOUT" switch
- // you will see mainThd.thd1, mainThd.thd2, and mainThd
- // all changing the same field "E.stat" on each other.
- //
- //----------------------------------------------------------------------------
- // This file is part of the Microsoft NGWS Runtime Samples.
- //
- // Copyright (C) 1998-2000 Microsoft Corporation. All rights reserved.
- //===========================================================================
- using System;
- using System.Threading;
-
- public class ThdRelStaticSample
- {
- public E E1; // object E1 will be one instance of class E
- public E E2; // object E2 will be another instance of class E
- public Thread thd1; // Thread thd1 will be running on object E1, method Run1
- public Thread thd2; // Thread thd1 will be running on object E1, method Run2
-
- public ThdRelStaticSample( ) {
- E1 = new E( );
- E2 = new E( );
- thd1 = new Thread(new ThreadStart(E1.Run1));
- thd2 = new Thread(new ThreadStart(E1.Run2));
- thd1.Start( );
- thd2.Start( );
- }
-
- static public void Main(String[] args) {
- #if !WITHOUT
- Console.WriteLine("Thread Relative Statics Sample with \"[ThreadStaticAttribute( )]\"");
- #else
- Console.WriteLine("Thread Relative Statics Sample WITHOUT \"[ThreadStaticAttribute( )]\"");
- #endif
- ThdRelStaticSample mainThd = new ThdRelStaticSample( );
-
- lock(mainThd.E1) // Monitor.Enter on the same object that mainThd.thd1
- { // and mainThd.thd2 using for coordinating
- Console.Write("mainThd.E1 "); // Console output on
- mainThd.E1.DebugOut( );
- } // Monitor.Exit(mainThd.E1);
-
- mainThd.E1.Change( ); // Adds E.jumpChange to E.stat
-
- lock(mainThd.E1) // Monitor.Enter on the same object that mainThd.thd1
- { // and mainThd.thd2 using for cooridinating
- Console.Write("mainThd.E2 "); // Console output on
- mainThd.E2.DebugOut( );
- } // Monitor.Exit(mainThd.E1);
-
- mainThd.E2.Change( ); // Adds E.jumpChange to E.stat
-
- mainThd.thd1.Join( ); // Join on mainThd.thd1, no Stop. Thread to run to completion
- mainThd.thd2.Stop( ); // Stop on mainThd.thd2.
- mainThd.thd2.Join( ); // Join on mainThd.thd2. (Now both of these threads are dead)
-
- Console.Write("mainThd.E1 "); // mainThd.thd1 and mainThd.thd2 are dead, so we
- mainThd.E1.DebugOut( ); // don't need to coordinate Console with anyone.
-
- mainThd.E1.Change( ); // Adds E.jumpChange to E.stat
-
- Console.Write("mainThd.E2 "); // mainThd.thd1 and mainThd.thd2 are dead, so we
- mainThd.E2.DebugOut( ); // don't need to coordinate Console with anyone.
- }
- }
-
- public class E
- {
- // "[ThreadStaticAttribute( )]" is an attribute, much like "public" and/or "static"
- // In the next few lines, the "[ThreadStaticAttribute( )]" is applied to the
- // field E.stat if this code is compiled without the "/D:WITHOUT"
- // switch on the CSharp compiler.
- #if !WITHOUT
- [ThreadStaticAttribute( )]
- #endif
- public static int stat;
- public static int startHere = 3;
- public static int jumpChange = 2;
- public static int loopRun1First = 10000;
- public static int loopRun1Second = 20000;
- public static int loopRun2First = -5000;
- public static int resetRun2First = 1000;
- public static int resetRun2Finally = 2001;
- public E( )
- {
- stat = startHere;
- }
-
- public void Run1( )
- {
- while(stat < loopRun1First)
- stat++;
-
- lock(this) // Monitor.Enter(this)
- {
- Console.Write(" Run1 L1 "); // loopRun1First, Loop One.
- DebugOut( );
- } // Monitor.Exit(this)
-
- while(stat < loopRun1Second)
- stat++;
-
- lock(this) // Monitor.Enter(this)
- {
- Console.Write(" Run1 L2 "); // loopRun1Second, Loop Two.
- DebugOut( );
- } // Monitor.Exit(this)
- }
-
- public void Run2( )
- {
- try
- {
- while(true)
- {
- stat--;
- if (stat == loopRun2First)
- {
- lock(this) // Monitor.Enter(this)
- {
- Console.Write(" Run2 ");
- DebugOut( );
- } // Monitor.Exit(this)
- stat = resetRun2First;
- }
- }
- }
- finally
- {
- lock(this) // Monitor.Enter(this) and Monitor.Exit(this)
- DebugOut( ); // as a wrapper around this single statement.
- stat = resetRun2Finally;
- lock(this) // Monitor.Enter(this)
- {
- Console.Write(" Run2 fin "); // Run2 is in the finally block
- DebugOut( );
- } // Monitor.Exit(this)
- }
- }
-
- public void Change( )
- {
- stat+=jumpChange;
- }
- public void DebugOut( )
- {
- Console.WriteLine("stat = {0}",stat);
- }
-
- }
-
- /*
-
- Output of TRSS.exe
-
- Thread Relative Statics Sample WITHOUT "[ThreadStaticAttribute( )]"
- mainThd.E1 stat = 3
- Run2 stat = -5000
- Run1 L1 stat = -5000
- Run2 stat = 20000
- Run1 L2 stat = -5000
- Run2 stat = -5000
- Run2 stat = -5000
- Run2 stat = -5000
- Run2 stat = -5000
- mainThd.E2 stat = -4998
- Run2 stat = -5000
- Run2 fin stat = 2001
- mainThd.E1 stat = 2001
- mainThd.E2 stat = 2003
-
- ======================================================================================
- Output of ThdRelStaticSample.exe
-
- Thread Relative Statics Sample with "[ThreadStaticAttribute( )]"
- mainThd.E1 stat = 3
- mainThd.E2 stat = 5
- Run2 stat = -5000
- Run1 L1 stat = 10000
- Run2 stat = -5000
- Run2 stat = -5000
- Run1 L2 stat = 20000
- Run2 stat = -5000
- Run2 fin stat = 2001
- mainThd.E1 stat = 7
- mainThd.E2 stat = 9
-
- */
-