Sunday, 9 April 2023

Multithreading With .NET

 This article explains how multithreading works. You will learn how the operating system manages thread execution and shows you how to manipulate the Thread class in your program to create and start managed threads.

 
This article covers the entire range of threading areas from thread creation, race conditions, deadlocks, monitors, mutexes, synchronization and semaphores and so on.
 

Multithreading Overview

 
A thread is an independent stream of instructions in a program. A thread is similar to a sequential program. However, a thread itself is not a program, it can't run on its own, instead it runs within a program's context.
 
The real usage of a thread is not about a single sequential thread, but rather using multiple threads in a single program. Multiple threads running at the same time and performing various tasks is referred as Multithreading. A thread is considered to be a lightweight process because it runs within the context of a program and takes advantage of resources allocated for that program.
Multithreading with .NET 
With the task manager, you can turn on the Thread column and see the processes and the number of threads for every process. Here, you can notice that only cmd.exe is has a single thread whereas all other applications use multiple threads.
 
Multithreading with .NET 
 
The operating system schedules threads. A thread has a priority and every thread has its own stack, but the memory for the program code and heap are shared among all threads of a single process.
 
A process consists of one or more threads of execution. A process always consists of at least one thread called the primary thread (Main() method in C# programs). A single-threaded process contains only one thread while a multithreaded process contains more than one thread for execution.
Multithreading with .NET 
On a computer, the operating system loads and starts applications. Each application or service runs as a separate process on the machine. The following image illustrates that there are quite a few processes actually running than there are actual applications running in the system. Many of these processes are background operating system processes that are started automatically when the OS loads.
 
Multithreading with .NET 
 
System.Threading Namespace
 
Like many other features, in .NET, System.Threading is the namespace that provides various types to help in construction of multithreaded applications.
 
TypeDescription
ThreadIt represents a thread that executes within the CLR. Using this, we can produce additional threads in an application domain.
MutexIt is used for synchronization between application domains.
MonitorIt implements synchronization of objects using Locks and Wait.
SmaphoreIt allows limiting the number of threads that can access a resource concurrently.
InterlockIt provides atomic operations for variables that are shared by multiple threads.
ThreadPoolIt allows you to interact with the CLR maintained thread pool.
ThreadPriorityThis represents the priority level such as High, Normal, Low.
 
System.Threading.Thread class
 
The Thread class allows you to create and manage the execution of managed threads in your program. These threads are called managed threads.
 
MemberTypeDescription
CurrentThreadStaticReturn a reference of current running thread.
SleepStaticSuspend the current thread for a specific duration.
GetDoaminStaticReturn a reference of current application domain.
CurrentContextStaticReturn a reference of current context in which the thread currently running.
PriorityInstance levelGet or Set the Thread priority level.
IsAliveInstance levelGet the thread state in form of True or False value.
StartInstance levelInstruct the CLR to start the thread.
SuspendInstance levelSuspend the thread.
ResumeInstance levelResume a previously suspended thread.
AbortInstance levelInstruct the CLR to terminate the thread.
NameInstance levelAllows establishing a name to thread.
IsBackgroundInstance levelIndicate whether a thread is running in background or not.
 

Multithreading Implementation

 
Obtaining Current Thread Information
 
To illustrate the basic use of the Thread type, suppose you have a console application in which the CurrentThread property retrieves a Thread object that represents the currently executing thread.
  1. using System;  
  2. using System.Threading;  
  3. namespace threading  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             Console.WriteLine("**********Current Thread Informations***************\n");  
  10.             Thread t = Thread.CurrentThread;  
  11.             t.Name = "Primary_Thread";  
  12.             Console.WriteLine("Thread Name: {0}", t.Name);  
  13.             Console.WriteLine("Thread Status: {0}", t.IsAlive);  
  14.             Console.WriteLine("Priority: {0}", t.Priority);  
  15.             Console.WriteLine("Context ID: {0}", Thread.CurrentContext.ContextID);  
  16.             Console.WriteLine("Current application domain: {0}",Thread.GetDomain().FriendlyName);  
  17.             Console.ReadKey();   
  18.         }  
  19.     }  
  20. }  
After compiling this application, the output will be as in the following;
 
Multithreading with .NET 
 
Simple Thread Creation
 
The following example explains the Thread class implementation in which the constructor of Thread class accepts a delegate parameter. After the Thread class object is created, you can start the thread with the Start() method as in the following;
  1. using System;  
  2. using System.Threading;  
  3. namespace threading  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             Thread t = new Thread(myFun);  
  10.              t.Start();  
  11.             Console.WriteLine("Main thread Running");  
  12.             Console.ReadKey();   
  13.         }  
  14.         static void myFun()  
  15.         {  
  16.             Console.WriteLine("Running other Thread");   
  17.         }  
  18.     }  
  19. }  
After running the application, you will get the following output of the two threads:
 
Multithreading with .NET 
 
The important point to be noted here is that, there is no guarantee of what output comes first, in other words which thread starts first. Threads are scheduled by the operating system. So which thread comes first can be different each time.
 
Background Thread
 
The process of the application keeps running as long as at least one foreground thread is running. If more than one foreground thread is running and the Main() method ends, the process of the application keeps active until all foreground threads finish their work, and by foreground thread termination all background threads will terminate immediately.
 
When you create a thread with the Thread class, you can define it as being either a foreground or background thread by setting the property IsBackground. The Main() method sets this property of the thread "t" to false. After setting the new thread, the main thread just writes to the console an end message. The new thread writes a start and an end message, and in between it sleeps for 2 seconds.
  1. using System;  
  2. using System.Threading;  
  3. namespace threading  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             Thread t = new Thread(myFun);  
  10.             t.Name = "Thread1";  
  11.             t.IsBackground = false;   
  12.             t.Start();  
  13.             Console.WriteLine("Main thread Running");  
  14.             Console.ReadKey();   
  15.         }  
  16.         static void myFun()  
  17.         {  
  18.             Console.WriteLine("Thread {0} started", Thread.CurrentThread.Name);  
  19.             Thread.Sleep(2000);   
  20.             Console.WriteLine("Thread {0} completed", Thread.CurrentThread.Name);   
  21.         }  
  22.     }  
  23. }  
When you compile this application, you will still see the completion message written to the console because the new thread is a foreground thread. Here, the output is as in the following;
 
Multithreading with .NET 
 
If you change the IsBackground property to true then the result shown at the console will be as in the following;
 
Multithreading with .NET 
 
Concurrency issues 
 
When starting multiple threads that access the same data, your program needs to ensure that any piece of shared data is protected against the possibility of numerous threads changing its value.
 
Race Condition
 
A race condition occurs if two or more threads access the same object and access to the shared state is not synchronized. To illustrate the problem of a Race condition, let's build a console application. This application uses the Test class to print 10 numbers by pausing the current thread for a random number of times. 
  1. using System;  
  2. using System.Threading;  
  3. namespace threading  
  4. {  
  5.     public class Test  
  6.     {  
  7.         public void Calculate()  
  8.         {    
  9.             for (int i = 0; i < 10; i++)  
  10.             {  
  11.                 Thread.Sleep(new Random().Next(5));  
  12.                 Console.Write(" {0},", i);  
  13.             }  
  14.             Console.WriteLine();  
  15.         }  
  16.     }  
  17.     class Program  
  18.     {  
  19.         static void Main(string[] args)  
  20.         {  
  21.             Test t = new Test();  
  22.             Thread[] tr = new Thread[5];  
  23.             for (int i = 0; i < 5; i++)  
  24.             {  
  25.                 tr[i] = new Thread(new ThreadStart(t.Calculate));  
  26.                 tr[i].Name = String.Format("Working Thread: {0}", i);  
  27.             }  
  28.             //Start each thread  
  29.             foreach (Thread x in tr)  
  30.             {  
  31.                 x.Start();  
  32.             }  
  33.             Console.ReadKey();  
  34.         }  
  35.     }  
  36. }  
After compiling this program, the primary thread within this application domain begins by producing five secondary threads. And each working thread is told to call the Calculate() method on the same Test class instance. Hence, all five threads start to access the Calculate() method simultaneously and since we have not taken any precaution to lock down this object's shared resources; this will lead towards the Race Condition and the application produces unpredictable output as in the following;
 
Multithreading with .NET 
 
Deadlocks
 
Having too much locking in an application can get your application into trouble. In a deadlock, at least two threads wait for each other to release a lock. As both threads wait for each other, a deadlock situation occurs and threads wait endlessly and the program stops responding.
 
Here, both the methods changed the state of objects obj1 and obj2 by locking them. The method DeadLock1() first locks obj1 and next for obj2 similarly method DeadLock2() first locks obj2 and then obj1. So lock for obj1 is released, next a thread switch occurs and the second method starts and gets the lock for obj2. The second thread now waits for the lock of obj1. Both of threads now wait and don't release each other. This is typically a deadlock situation.
  1. using System;  
  2. using System.Threading;  
  3. namespace threading  
  4. {  
  5.     class Program  
  6.     {  
  7.         static object obj1 = new object();  
  8.         static object obj2 = new object();  
  9.         public static void DeadLock1()  
  10.         {  
  11.             lock (obj1)  
  12.             {  
  13.                 Console.WriteLine("Thread 1 got locked");  
  14.                 Thread.Sleep(500);  
  15.                 lock (obj2)  
  16.                 {  
  17.                     Console.WriteLine("Thread 2 got locked");  
  18.                 }  
  19.             }  
  20.         }  
  21.         public static void DeadLock2()  
  22.         {  
  23.             lock (obj2)  
  24.             {  
  25.                 Console.WriteLine("Thread 2 got locked");  
  26.                 Thread.Sleep(500);  
  27.                 lock (obj1)  
  28.                 {  
  29.                     Console.WriteLine("Thread 1 got locked");  
  30.                 }  
  31.             }  
  32.         }  
  33.         static void Main(string[] args)  
  34.         {  
  35.             Thread t1 = new Thread(new ThreadStart(DeadLock1));  
  36.             Thread t2 = new Thread(new ThreadStart(DeadLock2));  
  37.             t1.Start();  
  38.             t2.Start();  
  39.             Console.ReadKey();  
  40.         }  
  41.     }  
  42. }  
Synchronization
 
Problems that can occur with multiple threads such as Race condition and deadlocks can be avoided by Synchronization. It is always suggested to avoid concurrency issues by not sharing data between threads. Of course, this is not always possible. If data sharing is unavoidable then you must use synchronization so that only one thread at a time accesses and changes shared states.
 
This section discusses various synchronization techniques.
 
Locks
 
We can synchronize access to shared resources using the lock keyword. By doing so, incoming threads cannot interrupt the current thread, preventing it from finishing its work. The lock keyword requires an object reference.
 
By taking the previous Race Condition problem, we can refine this program by implementing a lock on crucial statements to make it foolproof from a race conditions as in the following;
  1. public class Test  
  2. {  
  3.     public object tLock = new object();  
  4.     public void Calculate()  
  5.     {  
  6.         lock (tLock)  
  7.         {  
  8.             Console.Write(" {0} is Executing",Thread.CurrentThread.Name);  
  9.             for (int i = 0; i < 10; i++)  
  10.             {  
  11.                 Thread.Sleep(new Random().Next(5));  
  12.                 Console.Write(" {0},", i);  
  13.             }  
  14.             Console.WriteLine();  
  15.         }  
  16.     }  
  17. }  
After compiling this program, this time it produced the desired result as in the following. Here, each thread has sufficed opportunity to finish its tasks.
 
Multithreading with .NET 
 
Monitor
 
The lock statement is resolved by the compiler to the use of the Monitor class. The Monitor class is almost similar to a lock but its advantage is better control than the lock statement. You are able to instruct the lock's enter and exit explicitly, as shown in the code below. 
  1. object tLock = new object();  
  2. public void Calculate()  
  3. {  
  4.     Monitor.Enter(tLock);  
  5.     try  
  6.     {  
  7.       for (int i = 0; i < 10; i++)  
  8.       {  
  9.         Thread.Sleep(new Random().Next(5));  
  10.         Console.Write(" {0},", i);  
  11.       }  
  12.     }  
  13.     catch{}  
  14.     finally  
  15.     {  
  16.       Monitor.Exit(tLock);  
  17.     }  
  18.     Console.WriteLine();  
  19. }  
In fact, if you observe the IL code of the any application that uses the lock statement, you will find the Monitor class reference there as in the following;
 
Multithreading with .NET 
 
Using [Synchronization] Attribute
 
The [Synchronization] attribute is a member of System.Runtime.Remoting.Context namespace. This class level attribute effectively locks down all instance of the object for thread safety.
  1. using System.Threading;  
  2.   
  3. using System.Runtime.Remoting.Contexts;   
  4. [Synchronization]  
  5. public class Test:ContextBoundObject  
  6. {  
  7.     public void Calculate()  
  8.     {  
  9.         for (int i = 0; i < 10; i++)  
  10.         {  
  11.             Thread.Sleep(new Random().Next(5));  
  12.             Console.Write(" {0},", i);  
  13.         }  
  14.         Console.WriteLine();  
  15.     }  
  16. }  
Mutex
 
Mutex stands for Mutual Exclusion that offers synchronization across multiple threads. The Mutex calss is derived from WaitHandle, you can do a WaitOne() to acquire the mutex lock and be the owner of the mutex that time. The mutex is released by invoking the ReleaseMutex() method as in the following;
  1. using System;  
  2. using System.Threading;  
  3. namespace threading  
  4. {  
  5.     class Program  
  6.     {  
  7.         private static Mutex mutex = new Mutex();  
  8.         static void Main(string[] args)  
  9.         {  
  10.             for (int i = 0; i < 4; i++)  
  11.             {  
  12.                 Thread t = new Thread(new ThreadStart(MutexDemo));  
  13.                 t.Name = string.Format("Thread {0} :", i+1);  
  14.                 t.Start();  
  15.             }  
  16.             Console.ReadKey();  
  17.         }  
  18.         static void MutexDemo()  
  19.         {  
  20.             try  
  21.             {  
  22.                 mutex.WaitOne();   // Wait until it is safe to enter.  
  23.                 Console.WriteLine("{0} has entered in the Domain", Thread.CurrentThread.Name);  
  24.                 Thread.Sleep(1000);    // Wait until it is safe to enter.  
  25.                 Console.WriteLine("{0} is leaving the Domain\r\n", Thread.CurrentThread.Name);  
  26.             }  
  27.             finally  
  28.             {  
  29.                 mutex.ReleaseMutex();  
  30.             }  
  31.         }  
  32.     }  
  33. }  
Once you have successfully compiled this program, it shows when each new thread first enters into its application domain. Once it has finished its tasks then it is released and the second thread starts and so on.
 
Multithreading with .NET 
 
Semaphore
 
A semaphore is very similar to a Mutex but a semaphore can be used by multiple threads at once while a Mutex can't. With a Semaphore, you can define a count of how many threads are allowed to access the resources shielded by a semaphore simultaneously.
 
Here in the following example, 5 threads are created and 2 semaphores. In the constructor of the semaphore class, you can define the number of locks that can be acquired with a semaphore. 
  1. using System;  
  2. using System.Threading;  
  3. namespace threading  
  4. {  
  5.     class Program  
  6.     {  
  7.         static Semaphore obj = new Semaphore(2, 4);  
  8.         static void Main(string[] args)  
  9.         {  
  10.             for (int i = 1; i <= 5; i++)  
  11.             {  
  12.                 new Thread(SempStart).Start(i);  
  13.             }  
  14.             Console.ReadKey();  
  15.         }  
  16.         static void SempStart(object id)  
  17.         {  
  18.             Console.WriteLine(id + "-->>Wants to Get Enter");  
  19.             try  
  20.             {  
  21.                 obj.WaitOne();  
  22.                 Console.WriteLine(" Success: " + id + " is in!");     
  23.                 Thread.Sleep(2000);  
  24.                 Console.WriteLine(id + "<<-- is Evacuating");  
  25.             }  
  26.             finally  
  27.             {  
  28.                 obj.Release();  
  29.             }  
  30.         }  
  31.     }  
  32. }  
While we run this application, 2 semaphores are immediately created and the others wait because we have created 5 threads. So 3 are in the waiting state. The movement, any one of thread released the rest of created one by one as following.
 
Multithreading with .NET 

Wednesday, 5 April 2023

How to take MSSQL database offline or bring it online?

 Sometimes, you come across a situation when you are required to move the database files physically. Online databases will not allow you such moving operations on “online” status; therefore, you will require to take your database offline to accomplish it. You can do it from the SQL Server Management Studio interface as mentioned below.

Steps to Take MSSQL Database Offline

1. Log in to your SQL Server Management Studio. Please refer to how to connect SQL using management studio for more details.  

2. Expand the Databases option and locate the database that you wish to take offline.

Expand Databases Option and Locate your Database from List
3. Right-click the database and select Tasks >> Take Offline.

Right Click the Database and Select Tasks > Take Offline Option
4. Once this is done, it will show you a message as below:

A Message Appear After Taking a Database Offline

Steps to Bring MSSQL Database Online

1. Once you are done with transferring the database files, you will require to bring the database online again.

2. For that, again expand the Databases option and locate your offline database.

Expand Databases Option and Locate the Offline Database
3. Right-click the database and select Tasks >> Bring Online.

Right Click the Database and Select Tasks > Bring Online
4. Once the process is done, it will show you a message as below:

A Message Appear After Bringing a Database Online


Sunday, 2 April 2023

BreakPoints Are Not Working in Visual Studio

 Solution

  • Ensure that debug configuration, debug flag and full debug info are set on all assemblies.
  • Delete all bin and obj folders and all DLLs related to the project from the entire machine.
  • Recreate projects causing the problem from scratch.
  • Reboot.

Solution: Start debugging. As soon as you've arrived at a breakpoint or used Debug > Break All, use Debug > Windows > Modules. You'll see a list of all the assemblies that are loaded into the process. Locate the one you want to get debug info for. Right-click it and select Symbol Load Information. You'll get a dialog that lists all the directories where it looked for the .pdb file for the assembly. Verify that list against the actual .pdb location. Ensure it doesn't find an old one.

In normal projects, the assembly and its .pdb file should always have been copied by the IDE into the same folder as your .exe. The bin\Debug folder of your project. Make sure you remove one from the GAC if you've been playing with it.

Solution: Right-click the Solution in Solution Explorer, click "clean solution", this deletes all the compiled and temporary files associated with a solution.

Solution: Right-click on solution --> Properties

Look under Common Properties --> Startup Project
Select multiple startup projects
select Start action on the projects you need to debug.



Solution

  • Right-click on your project.
  • Select [Properties].
  • Select the [Build] tab.
  • Ensure [Define DEBUG constant] and [Define TRACE constant] are checked.
  • Click the [Advanced] button at the bottom of the Build tabpage.
  • Ensure that [Debug Info:] is set to [full].
  • Click [OK] and rebuild the project.

Solution: Disable the "Just My Code" option in the Debug/General settings.



Solution: Run Visual Studio as an administrator.

Solution: Simply follow the procedure below

  • Go to Debug from the menu bar.
  • Click on Attach to Process.
  • Near the Attach to option, click on the Select button.
  • The Select Code Type window will appear.
  • Now select the option Automatically determine the type of code to debug and click the OK button.



Solution: Browse to C:\Users\<YOUR USER>\AppData\Local\Temp\Temporary ASP.NET Files\vs

Delete everything in this directory!

Solution: 
Be sure your are in Debug Mode.

Saturday, 1 April 2023

Invalid Option ‘7.3’ For /langversion; Must Be ISO-1, ISO-2, Default

 This is one of the common errors we face in ASP.NET from time to time. This compiler error occurs sometimes because of version changes where the Dotnet compiler version and C# version are incompatible.

Exact Error

Compilation Error

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS1617: Invalid option ‘6’ for /langversion; must be ISO-1, ISO-2, 3, 4, 5 or Default

In short, we will below error in the compiler.

Compiler Error Message - Invalid option ‘7.3’ for /langversion; must be ISO-1, ISO-2, Default, Latest, or a valid version in range 1 to 7.1.

Solution 1

One of the easy solutions is to install and reinstall these two NuGet packages.

  • Microsoft.CodeDom.Providers.DotNetCompilerPlatform
  • Microsoft.Net.Compilers

Right Click on Project >> Manage NuGet Packages >> Installed as shown,

Manage NuGet Packages

Simply, uninstall and install again these packages.

Solution 2. Another way is to update the following NuGet packages (whichever installed) to resolve the problem,

  • Microsoft.CodeDom.Providers.DotNetCompilerPlatform
  • Microsoft.Net.Compilers

Solution 3: Pay attention to compiler “type” in the Web.Config file, when changing Framework version,

for 4.5 and C#5,

type="Microsoft.CSharp.CSharpCodeProvider...

for 4.6 and C#6,

type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatfor

Workaround: Change in webconfig,

<system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701">
          <providerOption name="CompilerVersion" value="v4.0"/>
      </compiler>
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
    </compilers>
  </system.codedom>
C#

Attribute  “compilerOptions” needs to be replaced: “langversion:6” -> ‘langversion:5“

This is how we can solve this compilation error.