Threads in C# - First Part

Threads in C# - First Part

It’s been a while since my last post, but I was gathering some information, reading some books, and running some labs to bring you this topic. I hope you really enjoy it.

I’m pretty sure all of us are familiar with the term Sequential, when we are developing application is common to block the UI while some operation is being executed in the background, when these applications doesn’t execute a significant operation we won’t notice it, but what happens when you need to run a very expensive operation in term of time and resources, well, this is when you have to come with something that let the user know that something is happening, for instance a Spinner or a type of Indicator, mmm but , what about if we want to continue doing something else whereas this operation is executing in the background, to give an specific example.

I have created this simple diagram to explain the following scenario where an specific user will go and start a process to synchronize Financial Operations for an specific customer, this will get information from a PostgreSQL DB and will put them into a MySQL DB, this process has to be reporting to our application so that the user can easily see the progress on the screen, since this process could take hours then the application needs to allow the user to continue doing any other operation he wants like reviewing some Daily Reports.

No alt text provided for this image

If our program was sequential then we will need to wait until the Sync process finishes to be able to switch to another screen, well, here is where Threads come into play. In this scenario we can easily say that we have a Main Thread (UI) and one more that is the Sync Transaction Thread.

I want to point something here before continuing, my intention with this Article is not to explain from an Architectural perspective how an Enterprise Application should be built, not, my idea is simpler, I want to share with all of you the variety of objects we can use to work along with Threads, it’s up to you how you want to use it.

Before beginning I need you to be aware of the following concepts:

Foreground Thread

These threads will continue to run until the last foreground thread is terminated. In the following example you can see that the application is terminated until the longest thread is finished.

No alt text provided for this image

Background Thread

Background threads are threads which will get terminated when all foreground threads are closed. The application won't wait for them to be completed. In the following example even though the background thread is still running as soon as the longest foreground thread finishes the applications is terminated without waiting for the finalization of the background thread.

No alt text provided for this image

Thread Synchronization

Thread synchronization is the concurrent execution of two or more threads that share critical resources. Threads should be synchronized to avoid critical resource use conflicts. Otherwise, conflicts may arise when parallel-running threads attempt to modify a common variable at the same time. This basically is making us aware of the fact that since Threads are processes that can be running at the same time and sharing same resources, we need to have a way to read and write in these resources without corrupting them when multiple threads are executing operation on them.?

Let’s split this up !

  • Simple blocking methods: This are methods that are part of the objects. For example, Thread.Sleep(), Task.Wait(), Thread.Join()
  • Exclusive Locking: Lock resources for one thread at a time, like Monitor.Enter(), Monitor.Exit(), Lock()
  • Non-Exclusive Locking: Lock resources for several threads at a time, like?SemaphoreSlim.
  • Signaling: Lock an specific resource until a signal is thrown, for example Monitor.Pulse(), ManualResetEvent.WaitOne(), AutoResetEvent.WaitOne()

Well, let’s begin with the examples.

SemaphoreSlim

I really love this one, it reminds me to a Bank Service Counter, as each Bank Teller is released one new customer may be attended, and this operation occurs simultaneously, every released space is going to be occupied by a new customer, it could be one space at a time or many spaces at a time. In the following example we will be using signaling to notify our SemaphoreSlim to release a space for a new Thread, like the Bank Service Counter example.

#1 - Declare our SemaphoreSlim class which will handle the logic to simulate a simultanius execution of 5 processes running at the same time, every time a space is released another process will come into play.?

using?System;
using?System.Threading;
using?System.Threading.Tasks;

namespace?ThreadImplementations
{
????internal?class?ThreadSemaphoreSlim
????{
???????
????????private?static?SemaphoreSlim?simpleSemaphore;
 
????????private?static?int?padding;
 
????????public?static?void?RunSimpleSemaphore()
????????{
????????????var?tasks?=?new?Task[5];
????????????simpleSemaphore?=?new?SemaphoreSlim(5);
 
????????????for?(int?i?=?0;?i?<?tasks.Length;?i++)
????????????{
????????????????tasks[i]?=?Task.Run(Enter);
????????????}
????????????Task.WaitAll(tasks);
????????????Console.WriteLine("This?will?be?executed?after?all?of?the?Tasks?are?already?completed");
????????}
 
????????private?static?void?Enter()
????????{
????????????var?thread?=?$"Thread?Id:?{Thread.CurrentThread.ManagedThreadId},?TaskId:?{Task.CurrentId}";
 
????????????Console.WriteLine($"Waiting..?{thread}");
????????????simpleSemaphore.Wait();
 
????????????Console.WriteLine($"Entered..?{thread}");
????????????Thread.Sleep(1000);
 
????????????simpleSemaphore.Release();
????????????Console.WriteLine($"Releasing..?{thread}");
????????}
}        

#2 - Let's call it.

using?System;
using?System.Collections.Generic;
using?System.Threading;
 
namespace?ThreadImplementations
{
????class?Program
????{
????????static?List<string>?list?=?new?List<string>();
????????private?static?ManualResetEvent?met?=?new?ManualResetEvent(false);
????????static?void?Main(string[]?args)
????????{
????????????ThreadSemaphoreSlim.RunSimpleSemaphore();
????????????Console.Read();
 
????????}
????}
}        

Well guys, this is the first Article about Threads, I hope you've really enjoyed it, in the next few days I'll be posting the second part with more interesting examples.

Have a happy coding.

要查看或添加评论,请登录

Olonyl Landeros的更多文章

社区洞察

其他会员也浏览了