
یادگیری سی شارپ از مفاهیم پایه تا پروژه محور: شیگرایی، کار با SQL و LINQ، ORMها (Entity Framework)، ساخت پروژه مدیریت رستوران با گزارشات حرفهای و امکانات کامل!
مشاهده بیشتر
یادگیری MVC Core از مبانی تا پیشرفته: شیگرایی، Routing، Entity Framework، امنیت، تست یونیت، Razor، Ajax، و پروژههای کاربردی! یک دوره کامل برای تسلط بر توسعه وب با ASP.NET Core. به صورت حضوری و آنلاین!
مشاهده بیشترمشخصات مقاله
Multi Treading در C#
Multi Treading
Thread به مسیر اجرای برنامه گفته میشود. هر یک از Threadها جریان منحصر به فردی از کنترل را تعریف میکنند. اگر برنامهی شما شامل عملیات پیچیده و زمانبر است، در این صورت بهتر است از مسیرهای اجرایی یا Threadهای مختلف استفاده کنید. به گونهای که هر یک از Threadها کار مشخصی را انجام دهند.
Threadها فرآیندهای سبک وزنی هستند. یکی از مثالهای معمول که میتوان برای کاربرد Thread بیان کرد، اجرای برنامهنویسی همزمان توسط سیستم عاملهای مدرن است. استفاده از Threadها باعث میشود از هدر رفت چرخهی CPU جلوگیری شود و بازدهی برنامه افزایش یابد.
در برنامههایی که تا الآن نوشتهایم یک Threadی تنها فقط یک فرآیند که نمونهی اجرایی از برنامه است را اجرا کرده است. با این حال در این صورت برنامه میتواند در یک زمان مشخص یک کار را انجام دهد. برای آن که برنامه بتواند در یک زمان بیش از یک کار را انجام دهد، باید آن را به Threadهای کوچکتر تقسیم کرد.
چرخهی عمر Thread
چرخهی عمر یک Thread زمانی آغاز میشود که شیئی از کلاس System.Threading.Thread ایجاد شود و با تمام شدن اجرا نیز به پایان میرسد.
در زیر میتوانید حالتهای مختلف چرخهی عمر یک Thread را مشاهده کنید:
- حالت آغاز نشده: این حالت مربوط به موقعیتی است که نمونهی Thread ایجاد شده است اما متد Start فراخوانی نشده است.
- حالت آمادهباش: این حالت مربوط به زمانی است که Thread آماده به اجرا است و در حال انتظار برای چرخهی CPU میباشد.
-
حالت غیر قابل اجرا: Threadها زمانی قابل اجرا نیستند که:
- متد Sleep فراخوانی شده باشد.
- متد Wait فراخوانی شده باشد.
- این Thread توسط عملیات ورودی/خروجی مسدود شده باشد.
- حالت مرگ: این حالت مربوط به زمانی است که اجرای Thread با موفقیت و یا به صورت ناموفق تمام شده باشد.
Thread اصلی (Main Thread)
در C# کلاس System.Threading.Thread در مواقعی کاربرد دارد که بخواهیم با چندین Thread کار کنیم. با استفاده از این کلاس میتوان تک تک Threadها را در یک برنامهی چند Threadای ایجاد کرد و به آنها دسترسی پیدا کرد. به اولین Threadای که قرار است در یک فرآیند اجرا شود Threadی اصلی گفته میشود.
زمانی که یک برنامهی C# شروع به اجرا شدن میکند، Threadی اصلی به صورت خودکار ایجاد میشود. Thread هایی که با استفاده از کلاس Thread ایجاد میشوند، Threadهای فرزند Threadی اصلی نامیده میشوند. میتوانید با استفاده از ویژگی CurrentThread کلاس Thread دسترسی پیدا کنید.
در برنامهی زیر اجرای Threadی اصلی نشان داده شده است:
using System; using System.Threading; namespace MultithreadingApplication { class MainThreadProgram { static void Main(string[] args) { Thread th = Thread.CurrentThread; th.Name = "MainThread"; Console.WriteLine("This is {0}", th.Name); Console.ReadKey(); } } }
زمانی که کد بالا کامپایل و اجرا شود، نتیجه به صورت زیر نمایش داده میشود:
This is MainThread
ویژگیها و متدهای کلاس Thread
در جدول زیر برخی از پرکاربردترین ویژگیهای کلاس Thread نشان داده شده است:
در جدول زیر برخی از متدهای پرکاربرد کلاس Thread نشان داده شده است:
پردازندهای که Threadی فعلی را اجرا میکند نمیتواند ترتیب دستورالعملها را به هم بزند به گونهای که دسترسی به حافظه قبل از فراخوانی MemoryBarrier بعد از دسترسی به حافظهای اجرا شود که به دنبال فراخوانی MemoryBarrier میآید.
public static double VolatileRead(ref double address)
public static int VolatileRead(ref int address)
public static Object VolatileRead(ref Object address)
public static void VolatileWrite(ref double address, double value)
public static void VolatileWrite(ref int address, int value)
public static void VolatileWrite(ref Object address, Object value)
ایجاد Threadها
Threadها را میتوان با بسط دادن کلاس Thread ایجاد کرد. بعد از این کار این کلاس جهت آغاز اجرای Threadی فرزند متد Start() را فراخوانی میکند.
در برنامهی زیر این مفهوم نشان داده شده است:
using System; using System.Threading; namespace MultithreadingApplication { class ThreadCreationProgram { public static void CallToChildThread() { Console.WriteLine("Child thread starts"); } static void Main(string[] args) { ThreadStart childref = new ThreadStart(CallToChildThread); Console.WriteLine("In Main: Creating the Child thread"); Thread childThread = new Thread(childref); childThread.Start(); Console.ReadKey(); } } }
زمانی که کد بالا کامپایل و اجرا شود، نتیجه به صورت زیر نمایش داده میشود:
In Main: Creating the Child thread Child thread starts
مدیریت Threadها
کلاس Thread متدهای مختلفی را فراهم میکند که به کمک آنها میتوان Threadها را مدیریت کرد.
در مثال زیر کاربرد متد sleep() جهت توقف یک Thread برای زمان مشخص نشان داده شده است.
using System; using System.Threading; namespace MultithreadingApplication { class ThreadCreationProgram { public static void CallToChildThread() { Console.WriteLine("Child thread starts"); // the thread is paused for 5000 milliseconds int sleepfor = 5000; Console.WriteLine("Child Thread Paused for {0} seconds", sleepfor / 1000); Thread.Sleep(sleepfor); Console.WriteLine("Child thread resumes"); } static void Main(string[] args) { ThreadStart childref = new ThreadStart(CallToChildThread); Console.WriteLine("In Main: Creating the Child thread"); Thread childThread = new Thread(childref); childThread.Start(); Console.ReadKey(); } } }
زمانی که کد بالا کامپایل و اجرا میشود، نتیجه به صورت زیر نمایش داده میشود:
In Main: Creating the Child thread Child thread starts Child Thread Paused for 5 seconds Child thread resumes
از بین بردن Thread
جهت از بین بردن Threadها باید از متد Abort() استفاده کنید.
زمان اجرا با throw کردن یک ThreadAbortException Thread را به صورت نیمهکاره متوقف میکند. با توجه با اینکه نمیتوان متوجه این استثنا شد، کنترل به بلوک نهایی ارسال میشود، البته اگر وجود داشته باشد.
در برنامه زیر این مطلب نشان داده شده است:
using System; using System.Threading; namespace MultithreadingApplication { class ThreadCreationProgram { public static void CallToChildThread() { try { Console.WriteLine("Child thread starts"); // do some work, like counting to 10 for (int counter = 0; counter <= 10; counter++) { Thread.Sleep(500); Console.WriteLine(counter); } Console.WriteLine("Child Thread Completed"); } catch (ThreadAbortException e) { Console.WriteLine("Thread Abort Exception"); } finally { Console.WriteLine("Couldn't catch the Thread Exception"); } } static void Main(string[] args) { ThreadStart childref = new ThreadStart(CallToChildThread); Console.WriteLine("In Main: Creating the Child thread"); Thread childThread = new Thread(childref); childThread.Start(); //stop the main thread for some time Thread.Sleep(2000); //now abort the child Console.WriteLine("In Main: Aborting the Child thread"); childThread.Abort(); Console.ReadKey(); } } }
زمانی که کد بالا کامپایل و اجرا شود، نتیجه به صورت زیر نمایش داده میشود:
In Main: Creating the Child thread Child thread starts 0 1 2 In Main: Aborting the Child thread Thread Abort Exception Couldn't catch the Thread Exception