Threading
As we all know, thread is an independent process which has its own memory and they will perform certain operation (if they are assigned to do so). In this whole blog post, we are going to discuss on executing some query with multiple thread, so that we execute them in parallel, rather sequential. Here is my function which will execute a query in my SQL server.public static void ConnectDBAndExecuteQuery() { try { string sqlQuery = "insert into tblMasterLookup Values (" + Thread.CurrentThread.Name + ",'Test','2.0','Myapplication',GetDate())"; string connectionString = @"Server=.\SQLEXPRESS;Database=AUTODATA;Password=abc@123;User ID=sa"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlCommand command = new SqlCommand(sqlQuery, connection)) { command.CommandTimeout = 80; command.ExecuteNonQuery(); Console.WriteLine("Executed Thread.. " + Thread.CurrentThread.Name); } } } catch (Exception e) { Console.WriteLine(e.Message); } }
Here is the code to Create Threads. I am going to use ThreadStart delegate to perform execution of method
public static void CreateThread(int ThreadCount) { Thread[] workerThread = new Thread[ThreadCount]; for (int i = 0; i < ThreadCount; i++) { workerThread[i] = new Thread(new ThreadStart(ConnectDBAndExecuteQueryWithLock)); workerThread[i].Name = i.ToString(); workerThread[i].Start(); } }As you can see here if I execute the code, I will get the output as shown

Thread Safety
There are chances that your thread may be interrupted by some other thread, hence we need to use the lock as shown, and here is the updated method.public static void ConnectDBAndExecuteQueryWithLock() { lock (threadLock) { try { string sqlQuery = "insert into tblMasterLookup Values (" + Thread.CurrentThread.Name + ",'Test','2.0','Myapplication',GetDate())"; string connectionString = @"Server=.\SQLEXPRESS;Database=AUTODATA;Password=abc@123;User ID=sa"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlCommand command = new SqlCommand(sqlQuery, connection)) { command.CommandTimeout = 80; command.ExecuteNonQuery(); Console.WriteLine("Executed Thread.. " + Thread.CurrentThread.Name); } } } catch (Exception e) { Console.WriteLine(e.Message); } } }We need to create a threadlock variable of type object
private static object threadLock = new object();Now we can ensure that our thread is safe from other threads. Here is the data executed (inserted) time for both with and without thread lock result in table

Parallel Execution
I am going to do the same stuff executing them in Parallel using Task Parallel Library (TPL), but here creating and managing thread is not done by me, rather .Net and CLR will take care of it. Here is the codepublic static void WithTPL(int ThreadCount) { //Create Parallel.For to execute the task Parallel.For(0, ThreadCount, i => { ConnectDBAndExecuteQuery(i); }); }As you can see in the code I am using Parallel.For to execute the ConnectDBAndExecuteQuery() method, the for loop will be iterated for the threadcount which I am passing as parameter, but here I am not creating the thread rather CLR will do instead. Here is the output, here I have added Thread.CurrentThread.ManagedThreadId to show the ManagedThreadID


Limiting Parallel Threads with ParallelOptions
We can also limit the parallel threads from 4 to 2 or we can increase the same from 2 to 10 using ParallelOptions class Here is the self-explanatory codeParallelOptions options = new ParallelOptions(); options.MaxDegreeOfParallelism = 2;Now let’s change our code to have ParallelOptions in our Parallel.For method
public static void WithTPLAndParallelOptions(int ThreadCount) { ParallelOptions options = new ParallelOptions(); options.MaxDegreeOfParallelism = 2; //Create Parallel.For to execute the task Parallel.For(0, ThreadCount, options, i => { ConnectDBAndExecuteQuery(i); }); }Now the output looks like this

Is it possible to increase the speed of writing to the database?
Good article . a quick question : why do we have to open multiple connections within the parallel loop? If I open up an connection with Using block and put the parallel loop inside it what side effects will it cause? guess it will look the db table but just trying to understand why is it that we are opening multiple connections
How can avoid Primary Key constraint – Duplicate Key error while doing Insert using Parallel Task Library.
if (CheckIfSkuExists(testSku))
{
ExecuteInlineUpdate(testSku);
//Console.WriteLine(“Inline Update executed”);
}
else
{
ExecuteInlineInsert(testSku);
//Console.WriteLine(“Inline Insert executed”);
}