ASP.NET - Multi Threading

thread به عنوان مسیر اجرای یک برنامه تعریف می شود. هر رشته یک جریان کنترل منحصر به فرد را تعریف می کند. اگر برنامه شما شامل عملیات پیچیده و وقت گیر مانند دسترسی به پایگاه داده یا برخی عملیات شدید I/O است، در آن صورت تنظیم مسیرهای اجرایی یا رشته های مختلف، با هر رشته ای که کار خاصی را انجام می دهد، اغلب مفید است.نخ ها فرآیندهای سبک وزنی هستند. یکی از نمونه های رایج استفاده از thread اجرای برنامه نویسی همزمان توسط سیستم عامل های مدرن است. استفاده از thread ها باعث صرفه جویی در اتلاف چرخه CPU و افزایش کارایی برنامه می شود.تا اینجا ما برنامه هایی را کامپایل کردیم که در آن یک رشته به عنوان یک فرآیند واحد اجرا می شود که نمونه در حال اجرا برنامه است. با این حال، به این ترتیب برنامه می تواند یک کار را در یک زمان انجام دهد. برای اینکه چندین کار را در یک زمان اجرا کند، می توان آن را به رشته های کوچکتر تقسیم کرد.در Net، threading از طریق فضای نام "System.Threading" مدیریت می شود. ایجاد یک متغیر از نوع System.Threading.Thread به شما این امکان را می دهد که یک رشته جدید برای شروع کار ایجاد کنید. این به شما امکان می دهد تا رشته های فردی را در یک برنامه ایجاد کرده و به آنها دسترسی داشته باشید.ایجاد موضوعیک thread با ایجاد یک شی Thread ایجاد می شود و به سازنده آن یک مرجع ThreadStart می دهد.ThreadStart childthreat = new ThreadStart(childthreadcall);چرخه زندگی نخچرخه زندگی یک thread زمانی شروع می شود که یک شی از کلاس System.Threading.Thread ایجاد می شود و زمانی که thread خاتمه می یابد یا اجرا به پایان می رسد.حالات مختلف در چرخه زندگی یک نخ به شرح زیر است:حالت شروع نشده: وضعیتی است که نمونه thread ایجاد می شود اما متد Start فراخوانی نمی شود.حالت آماده: وضعیتی است که thread برای اجرا آماده است و در انتظار چرخه CPU است.حالت غیر قابل اجرا: یک رشته قابل اجرا نیست، زمانی که:روش خواب نامیده شده استروش انتظار فراخوانی شده استتوسط عملیات I/O مسدود شده استحالت مرده: وضعیتی است که thread اجرا شده یا سقط شده است.اولویت موضوعویژگی Priority کلاس Thread اولویت یک رشته را نسبت به دیگری مشخص می کند. زمان اجرا .Net رشته آماده را با بالاترین اولویت انتخاب می کند.اولویت ها را می توان به صورت زیر دسته بندی کرد:بالاتر از حد معمولکمتر از عادیبالاترینپایین ترینطبیعیهنگامی که یک رشته ایجاد می شود، اولویت آن با استفاده از ویژگی Priority کلاس thread تنظیم می شود.NewThread.Priority = ThreadPriority.Highest;ویژگی‌ها و روش‌های موضوعکلاس Thread دارای ویژگی های مهم زیر است:توضیحات ملکCurrentContext زمینه فعلی را که thread در آن اجرا می شود را دریافت می کند.CurrentCulture فرهنگ موضوع فعلی را می گیرد یا تنظیم می کند.CurrentPrinciple اصل فعلی رشته را برای امنیت مبتنی بر نقش می گیرد یا تنظیم می کند.CurrentThread رشته در حال اجرا را دریافت می کند.CurrentUICulture فرهنگ فعلی مورد استفاده توسط مدیر منابع را برای جستجوی منابع خاص فرهنگ در زمان اجرا دریافت یا تنظیم می کند.ExecutionContext یک شی ExecutionContext دریافت می کند که حاوی اطلاعاتی در مورد زمینه های مختلف رشته فعلی است.IsAlive مقداری را دریافت می کند که وضعیت اجرای رشته فعلی را نشان می دهد.IsBackground مقداری را دریافت می کند یا تنظیم می کند که نشان می دهد آیا نخ یک رشته پس زمینه است یا نه.IsThreadPoolThread مقداری را دریافت می کند که نشان می دهد آیا یک رشته به مجموعه رشته مدیریت شده تعلق دارد یا خیر.ManagedThreadId یک شناسه منحصر به فرد برای رشته مدیریت شده فعلی دریافت می کند.Name نام موضوع را می گیرد یا تنظیم می کند.اولویت مقداری را می گیرد یا تنظیم می کند که اولویت زمان بندی یک رشته را نشان می دهد.ThreadState مقداری را دریافت می کند که شامل حالات رشته فعلی است.کلاس Thread متدهای مهم زیر را دارد:شرح روشهاAbort یک ThreadAbortException را در رشته ای که بر روی آن فراخوانی شده است، برای شروع فرآیند پایان دادن به رشته ایجاد می کند. فراخوانی این متد معمولا باعث خاتمه thread می شود.AllocateDataSlot یک اسلات داده بدون نام را در همه رشته ها اختصاص می دهد. برای عملکرد بهتر، به جای آن از فیلدهایی استفاده کنید که با ویژگی ThreadStaticAttribute مشخص شده اند.AllocateNamedDataSlot یک اسلات داده با نام را در همه رشته ها اختصاص می دهد. برای عملکرد بهتر، به جای آن از فیلدهایی استفاده کنید که با ویژگی ThreadStaticAttribute مشخص شده اند.BeginCriticalRegion به میزبانی اطلاع می‌دهد که اجرا در شرف ورود به ناحیه‌ای از کد است که در آن اثرات قطع رشته یا استثناء کنترل نشده ممکن است سایر وظایف در دامنه برنامه را به خطر بیندازد.BeginThreadAffinity به میزبانی اطلاع می دهد که کد مدیریت شده در شرف اجرای دستورالعمل هایی است که به هویت رشته فعلی سیستم عامل فیزیکی بستگی دارد.EndCriticalRegion به میزبانی اطلاع می‌دهد که اجرا در شرف ورود به ناحیه‌ای از کد است که در آن اثرات قطع رشته یا استثناء کنترل نشده محدود به کار فعلی است.EndThreadAffinity به میزبانی اطلاع می دهد که کد مدیریت شده اجرای دستورالعمل هایی را که به هویت رشته فعلی سیستم عامل فیزیکی بستگی دارد، به پایان رسانده است.FreeNamedDataSlot ارتباط بین یک نام و یک اسلات را برای همه رشته ها در فرآیند حذف می کند. برای عملکرد بهتر، به جای آن از فیلدهایی استفاده کنید که با ویژگی ThreadStaticAttribute مشخص شده اند.GetData مقدار را از شکاف مشخص شده در رشته فعلی، در دامنه فعلی رشته فعلی بازیابی می کند. برای عملکرد بهتر، به جای آن از فیلدهایی استفاده کنید که با ویژگی ThreadStaticAttribute مشخص شده اند.GetDomain دامنه فعلی که رشته فعلی در آن در حال اجرا است را برمی گرداند.GetDomainID یک شناسه دامنه کاربردی منحصر به فرد را برمی گرداند.GetNamedDataSlot یک اسلات داده با نام را جستجو می کند. برای عملکرد بهتر، به جای آن از فیلدهایی استفاده کنید که با ویژگی ThreadStaticAttribute مشخص شده اند.وقفه رشته ای را که در وضعیت رشته WaitSleepJoin است قطع می کند.Join تا زمانی که یک رشته به پایان برسد، رشته تماس گیرنده را مسدود می کند، در حالی که به انجام پمپاژ استاندارد COM و SendMessage ادامه می دهد. این روش دارای اشکال مختلف بارگذاری شده است.MemoryBarrier دسترسی به حافظه را به صورت زیر همگام‌سازی می‌کند: پردازنده‌ای که رشته فعلی را اجرا می‌کند نمی‌تواند دستورات را به گونه‌ای تغییر دهد که دسترسی‌های حافظه قبل از تماس با MemoryBarrier پس از دسترسی‌های حافظه که پس از تماس MemoryBarrier اجرا می‌شوند، اجرا شوند.ResetAbort لغو درخواست شده برای رشته فعلی را لغو می کند.SetData داده ها را در شکاف مشخص شده در رشته در حال اجرا، برای دامنه فعلی آن رشته تنظیم می کند. برای عملکرد بهتر، به جای آن از فیلدهایی که با ویژگی ThreadStaticAttribute مشخص شده اند استفاده کنید.شروع یک موضوع را شروع می کند.Sleep نخ را برای مدتی مکث می کند.SpinWait باعث می شود که یک رشته به تعداد دفعات تعیین شده توسط پارامتر تکرارها منتظر بماند.VolatileRead() مقدار یک فیلد را می خواند. این مقدار آخرین مقداری است که توسط هر پردازنده ای در رایانه نوشته شده است، صرف نظر از تعداد پردازنده ها یا وضعیت حافظه پنهان پردازنده. این روش دارای اشکال مختلف بارگذاری شده است.VolatileWrite() یک مقدار را فوراً در یک فیلد می نویسد، به طوری که مقدار برای همه پردازنده های کامپیوتر قابل مشاهده باشد. این روش دارای اشکال مختلف بارگذاری شده است.Yield باعث می شود که رشته فراخوانی به رشته دیگری که آماده اجرا بر روی پردازنده فعلی است اجرا شود. سیستم عامل موضوعی را که باید به آن تسلیم شود انتخاب می کند.مثالمثال زیر کاربردهای کلاس Thread را نشان می دهد. صفحه دارای یک کنترل برچسب برای نمایش پیام ها از رشته فرزند است. پیام های برنامه اصلی مستقیماً با استفاده از متد Response.Write () نمایش داده می شوند. از این رو آنها در بالای صفحه ظاهر می شوند.فایل منبع به شرح زیر است:<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="threaddemo._Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title> Untitled Page </title> </head> <body> <form id="form1" runat="server"> <div> <h3>Thread Example</h3> </div> <asp:Label ID="lblmessage" runat="server" Text="Label"> </asp:Label> </form> </body> </html>کد پشت فایل به شرح زیر است:using System;using System.Collections;using System.Configuration;using System.Data;using System.Linq;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.HtmlControls;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Xml.Linq;using System.Threading;namespace threaddemo{ public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ThreadStart childthreat = new ThreadStart(childthreadcall); Response.Write("Child Thread Started <br/>"); Thread child = new Thread(childthreat); child.Start(); Response.Write("Main sleeping for 2 seconds.......<br/>"); Thread.Sleep(2000); Response.Write("<br/>Main aborting child thread<br/>"); child.Abort(); } public void childthreadcall() { try{ lblmessage.Text = "<br />Child thread started <br/>"; lblmessage.Text += "Child Thread: Coiunting to 10"; for( int i =0; i<10; i++) { Thread.Sleep(500); lblmessage.Text += "<br/> in Child thread </br>"; } lblmessage.Text += "<br/> child thread finished"; }catch(ThreadAbortException e){ lblmessage.Text += "<br /> child thread - exception"; }finally{ lblmessage.Text += "<br /> child thread - unable to catch the exception"; } } }}موارد زیر را رعایت کنیدهنگامی که صفحه بارگذاری می شود، یک رشته جدید با مرجع متد () childthreadcall شروع می شود. فعالیت های موضوع اصلی مستقیماً در صفحه وب نمایش داده می شوند.رشته دوم اجرا می شود و پیام هایی را به کنترل برچسب ارسال می کند.نخ اصلی 2000 میلی‌ثانیه می‌خوابد و در طی آن نخ فرزند اجرا می‌شود.نخ فرزند تا زمانی که توسط نخ اصلی سقط شود اجرا می شود. ThreadAbortException را افزایش می دهد و خاتمه می یابد.کنترل به موضوع اصلی باز می گردد.پس از اجرا، برنامه پیام های زیر را ارسال می کند: