Showing posts with label C# Thread. Show all posts
Showing posts with label C# Thread. Show all posts

C# Sample code :shows a threading Trap

using System;
using System.Threading;

namespace ThreadTrap1
{
/// <summary>
/// This example shows a threading Trap, you simply can't
/// rely on threads executing in the order in which they
/// are started.
/// </summary>
class Program
{
static void Main(string[] args)
{

Thread T1 = new Thread(new ThreadStart(Increment));
Thread T2 = new Thread(new ThreadStart(Increment));
T1.Name = "T1";
T2.Name = "T2";
T1.Start();
T2.Start();
Console.ReadLine();
}


private static void Increment()
{
for (int i = 0; i < 100000;i++ )
if (i % 10000 == 0)
Console.WriteLine("Thread Name {0}",
Thread.CurrentThread.Name);
WriteDone(Thread.CurrentThread.Name);
}


private static void WriteDone(string threadName)
{
switch (threadName)
{
case "T1" :
Console.WriteLine("T1 Finished");
break;
case "T2":
Console.WriteLine("T2 Finished");
break;
}
}
}
}

Resume Threads

There used to be a way to pause threads using the Resume() method. But this is now deprecated, so you must use alternative methods, such as WaitHandles. To demonstrate this there is a combined application that covers Pause/Resume and Abort of background threads

Pause threads

There used to be a way to pause threads using the Pause() method. But this is now deprecated, so you must use alternative methods, such as WaitHandles. To demonstrate this there is a combined application that covers Pause/Resume and Abort of background threads

C# Sample Code : ThreadInterrupt

using System;
using System.Threading;

namespace ThreadInterrupt
{
   class Program
   {

       public static Thread sleeper;
       public static Thread waker;

       public static void Main(string[] args)
       {
           Console.WriteLine("Enter Main method");
           sleeper = new Thread(new ThreadStart(PutThreadToSleep));
           waker = new Thread(new ThreadStart(WakeThread));
           sleeper.Start();
           waker.Start();
           Console.WriteLine("Exiting Main method");
           Console.ReadLine();

       }

       //thread sleeper threadStart
       private static void PutThreadToSleep()
       {
           for (int i = 0; i < 50; i++)
           {
               Console.Write(i + " ");
               if (i == 10 || i == 20 || i == 30)
               {
                   try
                   {
                       Console.WriteLine("Sleep, Going to sleep at {0}",
                           i.ToString());
                       Thread.Sleep(20);
                   }
                   catch (ThreadInterruptedException e)
                   {
                       Console.WriteLine("Forcibly ");
                   }
                   Console.WriteLine("woken");
               }
           }
       }

       //thread waker threadStart
       private static void WakeThread()
       {

           for (int i = 51; i < 100; i++)
           {
               Console.Write(i + " ");

               if (sleeper.ThreadState == ThreadState.WaitSleepJoin)
               {
                   Console.WriteLine("Interrupting sleeper");
                   sleeper.Interrupt();
               }
           }

       }
   }
}

What is Thread Interrupt?

When a thread is put to sleep, the thread goes into the WaitSleepJoin state. If the thread is in this state it may be placed back in the scheduling queue by the use of the Interrupt method. Calling Interrupt when a thread is in the WaitSleepJoin state will cause a ThreadInterruptedException to be thrown, so any code that is written needs to catch this.

C# Sample code : for Thread.Sleep

using System;
using System.Threading;

namespace ThreadSleep
{
   class Program
   {

       public static Thread T1;
       public static Thread T2;

       public static void Main(string[] args)
       {
           Console.WriteLine("Enter Main method");

           T1 = new Thread(new ThreadStart(Count1));
           T2 = new Thread(new ThreadStart(Count2));
           T1.Start();
           T2.Start();
           Console.WriteLine("Exit Main method");
           Console.ReadLine();

       }

       //thread T1 threadStart
       private static void Count1()
       {
           Console.WriteLine("Enter T1 counter");
           for (int i = 0; i < 50; i++)
           {
               Console.Write(i + " ");
               if (i == 10)
                   Thread.Sleep(1000);
           }
           Console.WriteLine("Exit T1 counter");
       }

       //thread T2 threadStart
       private static void Count2()
       {
           Console.WriteLine("Enter T2 counter");
           for (int i = 51; i < 100; i++)
           {
               Console.Write(i + " ");
               if (i == 70)
                   Thread.Sleep(5000);
           }
           Console.WriteLine("Exit T2 counter");
       }
   }
}

C# Sample code : for Join 2 Threads

using System.Threading;

namespace ThreadJoin
{
   class Program
   {

       public static Thread T1;
       public static Thread T2;

       public static void Main(string[] args)
       {
           T1 = new Thread(new ThreadStart(First));
           T2 = new Thread(new ThreadStart(Second));
           T1.Name = "T1";
           T2.Name = "T2";
           T1.Start();
           T2.Start();
           Console.ReadLine();

       }

       //thread T1 threadStart
       private static void First()
       {
           for (int i = 0; i < 5; i++)
           {
               Console.WriteLine(
                   "T1 state [{0}], T1 showing {1}",
                   T1.ThreadState,  i.ToString());
           }
       }

       //thread T2 threadStart
       private static void Second()
       {
           //what the state of both threads
           Console.WriteLine(
               "T2 state [{0}] just about to Join, T1 state [{1}], CurrentThreadName={2}",
               T2.ThreadState, T1.ThreadState,
               Thread.CurrentThread.Name);

           //join T1
           T1.Join();

           Console.WriteLine(
               "T2 state [{0}] T2 just joined T1, T1 state [{1}], CurrentThreadName={2}",
               T2.ThreadState, T1.ThreadState,
               Thread.CurrentThread.Name);

           for (int i = 5; i < 10; i++)
           {
               Console.WriteLine(
                   "T2 state [{0}], T1 state [{1}], CurrentThreadName={2} showing {3}",
                   T2.ThreadState, T1.ThreadState,
                   Thread.CurrentThread.Name, i.ToString());
           }

           Console.WriteLine(
               "T2 state [{0}], T1 state [{1}], CurrentThreadName={2}",
               T2.ThreadState, T1.ThreadState,
               Thread.CurrentThread.Name);
       }
   }
}

what are different thread states?

Running The thread has been started, it is not blocked, and there is no pending ThreadAbortException.

StopRequested The thread is being requested to stop. This is for internal use only.

SuspendRequested The thread is being requested to suspend.

Background The thread is being executed as a background thread, as opposed to a foreground thread. This state is controlled by setting the Thread.IsBackground property.

Unstarted The Thread.Start method has not been invoked on the thread.

Stopped The thread has stopped.

WaitSleepJoin  The thread is blocked. This could be the result of calling Thread.Sleep or Thread.Join, of requesting a lock — for example, by calling Monitor.Enter or Monitor.Wait — or of waiting on a thread synchronization object such as ManualResetEvent

AbortRequested The Thread.Abort method has been invoked on the thread, but the thread has not yet received the pending System.Threading.ThreadAbortException that will attempt to terminate it.

Aborted The thread state includes AbortRequested and the thread is now dead, but its state has not yet changed to Stopped.

C# Sample code: starts a worker thread, and a Timer

using System;
using System.Threading;


namespace CallBacks
{
   class Program
   {
       private string message;
       private static Timer timer;
       private static bool complete;


       static void Main(string[] args)
       {
           Program p = new Program();
           Thread workerThread = new Thread(p.DoSomeWork);
           workerThread.Start();

           //create timer with callback
           TimerCallback timerCallBack =
               new TimerCallback(p.GetState);
           timer = new Timer(timerCallBack, null,
               TimeSpan.Zero, TimeSpan.FromSeconds(2));

           //wait for worker to complete
           do
           {
               //simply wait, do nothing
           } while (!complete);

           Console.WriteLine("exiting main thread");
           Console.ReadLine();
       }


       public void GetState(Object state)
       {
           //not done so return
           if (message == string.Empty) return;
           Console.WriteLine("Worker is {0}", message);
           //is other thread completed yet, if so signal main
           //thread to stop waiting
           if (message == "Completed")
           {
               timer.Dispose();
               complete = true;
           }
       }

       public void DoSomeWork()
       {
           message = "processing";
           //simulate doing some work
           Thread.Sleep(3000);
           message = "Completed";
       }
   }
}

C# small program with a main thread and 2 worker threads

using System;
using System.Threading;

namespace StartingThreads
{
   class Program
   {
       static void Main(string[] args)
       {
           //no parameters
           Thread workerThread = new Thread(StartThread);
           Console.WriteLine("Main Thread Id {0}",
               Thread.CurrentThread.ManagedThreadId.ToString());
           workerThread.Start();

           //using parameter
           Thread workerThread2 = new Thread(ParameterizedStartThread);
           // the answer to life the universe and everything, 42 obviously
           workerThread2.Start(42);
           Console.ReadLine();
       }

       public static void StartThread()
       {
           for (int i = 0; i < 10; i++)
           {
               Console.WriteLine("Thread value {0} running on Thread Id {1}",
                   i.ToString(),
                   Thread.CurrentThread.ManagedThreadId.ToString());
           }
       }

       public static void ParameterizedStartThread(object value)
       {
           Console.WriteLine("Thread passed value {0} running on Thread Id {1}",
               value.ToString(),
               Thread.CurrentThread.ManagedThreadId.ToString());
       }
   }
}

Starting Threads [Code Sample]

Starting new Threads is pretty easy, we just need to use one of the Thread constructors, such as

Thread(ThreadStart)
Thread(ParameterizedThreadStart)

There are others, but these are the most common ways to start threads. Lets look at an example of each of these

Code With No Parameters

Thread workerThread = new Thread(StartThread);
Console.WriteLine("Main Thread Id {0}",
   Thread.CurrentThread.ManagedThreadId.ToString());
workerThread.Start();

....
....
public static void StartThread()
{
   for (int i = 0; i < 10; i++)
   {
       Console.WriteLine("Thread value {0} running on Thread Id {1}",
           i.ToString(),
           Thread.CurrentThread.ManagedThreadId.ToString());
   }
}

Code With Single Parameter


//using parameter
Thread workerThread2 = new Thread(ParameterizedStartThread);
// the answer to life the universe and everything, 42 obviously
workerThread2.Start(42);
Console.ReadLine();

....
....
public static void ParameterizedStartThread(object value)
{
   Console.WriteLine("Thread passed value {0} running on Thread Id {1}",
       value.ToString(),
       Thread.CurrentThread.ManagedThreadId.ToString());
}

how to execute code in a specific AppDomain

using System;
using System.Threading;

namespace LoadNewAppDomain
{
   class Program
   {
       static void Main(string[] args)
       {
           AppDomain domainA = AppDomain.CreateDomain("MyDomainA");
           AppDomain domainB = AppDomain.CreateDomain("MyDomainB");
           domainA.SetData("DomainKey", "Domain A value");
           domainB.SetData("DomainKey", "Domain B value");
           OutputCall();
           domainA.DoCallBack(OutputCall); //CrossAppDomainDelegate call
           domainB.DoCallBack(OutputCall); //CrossAppDomainDelegate call
           Console.ReadLine();
       }

       public static void OutputCall()
       {
           AppDomain domain = AppDomain.CurrentDomain;
           Console.WriteLine("the value {0} was found in {1}, running on thread Id {2}",
               domain.GetData("DomainKey"),domain.FriendlyName,
               Thread.CurrentThread.ManagedThreadId.ToString());
       }
   }
}

C# code for Setting AppDomain Data

using System;
using System.Threading;

namespace AppDomainData
{
   class Program
   {
       static void Main(string[] args)
       {
           Console.WriteLine("Fetching current Domain");
           //use current AppDomain, and store some data
           AppDomain domain = System.AppDomain.CurrentDomain;
           Console.WriteLine("Setting AppDomain Data");
           string name = "MyData";
           string value = "Some data to store";
           domain.SetData(name, value);
           Console.WriteLine("Fetching Domain Data");
           Console.WriteLine("The data found for key {0} is {1}",
               name, domain.GetData(name));
           Console.ReadLine();
       }
   }
}

What Are AppDomains?

When I talked about Processes earlier, I mentioned that Processes have
physically isolated memory and resources needed to maintain
themselves, and I also mentioned that a Process has at least 1 thread.
Microsoft also introduced 1 extra layer of abstraction/isolation
called an AppDomain. The AppDomain is not a physical isolation, but
rather a logic isolation within the Process. Since more than 1
AppDomain can exist in Process we get some benifits. For example until
we had an AppDomain Processes that needed to access each others data
had to use a Proxy, which introduced extra code and overhead. By using
a AppDomain it is possible to launch several applications within the
same Process. The same sort of isolation that exists with Processes is
also available for AppDomain.Threads can execure across application
domains without the overhead of inter process communication. This is
all encapsulated within the AppDomain class. Any time a namespace is
loaded in an application it is loaded into an AppDomain. The AppDomain
used will be the same as the calling code unless otherwise specified.
AppDomain may or may not contain threads, which is different to
Processes.

What is free threading?

What happens if we need our Process to do more than 1 thing, like query a web service and write to a database at the same time. Luckily we can split a Process to share the time slice allocated to it. This is done by spawning new threads in the current Process. These extra threads ares sometimes called worker threads. These worker threads share the processes memory space that is isolated from all other Processes on the system. The concept of spawning new threads within the same process is called free threading.

What is Time Slices?

With all these Processes all wanting a slice of the CPU time cycle how does it get managed. Well each Process is granted a slice of time (Quantum) on which it (the Process) may use the CPU. This slice of time should NEVER to considered a constant, it is effected by OS and CPU type.

What are Processes?

When a user starts an Application, memory and a whole host of resources are allocated for the Application. The pysichal seperation of this memory and resources is called a Process. An Application may launch more than 1 Process. Its important to note that Applications and Processes are not the same thing at all.

You should all know that you can view the running Processes/Application in Windows using Task Manager.