در این مقاله یاد خواهید گرفت که چگونه از ابزار BackgroundWorker استفاده کنید. این ابزار به شما کمک خواهد کرد که چندین کار و پروسه را همزمان انجام بدهید، بدون اینکه برنامه قفل یا Freeze کند.
مقدمه
اگر با مباحث Thread آشنا باشید، می دانید که Thread به پروسه برنامه این اجازه را میدهد چند کد و دستور را در آن واحد اجرا کند. در حالت عادی فقط یک دستور از برنامه می تواند اجرا شود. این روند ممکن است که محدودیت هایی را برای برنامه نویس ایجاد کند. برای مثال در صورتی که کاربر در حال کار با برنامه و اجرای برخی دستورات باشد، برنامه بتواند به طور خودکار عمل پشتیبان گیری از داده ها را انجام دهد. این امکان پذیر نخواهد شد مگر با استفاده از Thread.
BackgroundWorker نیز با استفاده از Threading می تواند این اعمال را برای شما انجام دهد. در حقیقت BackgroundWorker صورت ساده شده ای از Thread است. گرچه هنوز هم می توانید در صورت تمایل از کلاس Thread استفاده کنید.
حال اجازه دهید به بررسی کلاس BackgroundWorker بپردازیم.
تشریح BackgroundWorker
توابع:
RunWorkerAsync: آغاز اجرای دستورات.
این تابع باعث آغاز اجرای دستورات می شود. این تابع رویداد DoWork که کدهای برنامه نوشته شده است را فراخوانی خواهد کرد.
این تابع یک ورودی اختیاری دارد. اگر دستورات شما احتیاج به بک مقدار خاصی دارد می توانید آن را طریق این ورودی ارسال کنید.
در صورتی که قبلا این تابع را فراخوانی کرده اید و هنوز کار آن به پایان نرسیده است، اگر دوباره این تابع را فراخوانی کنید با خطای InvalidOperationException روبرو خواهید شد.
CancelAsync: توقف اجرای دستورات.
درخواستی را مبنی بر قطع شدن عملیات ثبت می کند. با فراخوانی این تابع مقدار CancellationPending به true تغییر پیدا خواهد کرد.
توجه کنید که با فراخوانی این تابع اجرای دستورات همان لحظه متوقف نخواهد شد. این وظیفه نویسنده کد خواهد بود که مقدار ویژگی CancellationPending را بررسی کرده و ادامه عملیات را قطع کند.
هشدار: همیشه مقدار CancellationPending را در درون رویداد DoWork بررسی کنید. در صورت عدم بررسی این ویژگی ، اجرای تابع CancelAsync تاثیری نخواهد داشت و اجرای دستورات قطع نخواهد شد.
نکته: برای استفاده از این تابع باید مقدار ویژگی WorkerSupportsCancellation را به تغییر دهید، در غیر اینصورت با خطای InvalidOperationException روبرو خواهید شد.
ReportProgress: اطلاع از وضعیت پیشرفت پروسه
در صورتی که می خواهید از وضعیت پیشرفت عملیات آگاهی پیدا کنید می توانید از این تابع استفاده کنید. این تابع را باید در درون رویداد DoWork فراخوانی کنید.
اجرای تابع ReportProgress باعث فراخوانی رویداد ProgressChanged خواهد شد. برای فراخوانی این رویداد باید مقدار ویژگی WorkerReportsProgress را به true تغییر دهید در غیر اینصورت با خطای InvalidOperationException روبرو خواهید شد.
ورودی این تابع عددی است که می تواند درصدی از مقداری باشد که پروسه شما انجام داده است.
رویدادها
DoWork
این رویداد زمانی فراخوانی می شود که تابع RunWorkerAsync را اجرا کنید. در این رویداد است که شما باید کد ها و دستورات خود را باید بنویسید. در اینجا است که می توانید کارهایی که نیاز به زمان زیادی هستند را بنویسید.
در صورتی که دستورات شما باید یک خروجی را برگرداند می توانید خروجی دستورات را به ویژگی result از ورودی این رویداد که از توع DoWorkEventArgs است ارسال کنید. در این صورت خروجی ارسال شده در رویداد RunWorkerCompleted در دسترس خواهد بود.
هشدار: در هنگام استفاده از این رویداد نباید هیچ دسترسی به کنترل های درون فرم انجام دهید. به جای این کار از رویداد های این کلاس استفاده کنید.
ProgressChanged
این رویداد زمانی فراخوانی می شود که تابع ReportProgress اجرا شود.
RunWorkerCompleted
این رویداد زمانی فراخوانی میشود که اجرای دستورات به پایان برسد، یا ادامه اجرا لغو شود و یا اینکه در حین اجرا خطا رخ دهد.
ویژگی error از ورودی این رویداد حاوی اطلاعات خطایی است که باعث قطع اجرا شده است. در صورتی که هیچ خطایی رخ نداده باشد مقدار برگشتی خالی خواهد بود.
ویژگی Cancelled از ورودی این رویداد مشخص می کند عملیات به خاطر فراخوانی تابع CancelAsync قطع شده است یا نه. این ویژگی زمانی مقدار دهی خواهد شد که شما در رویداد DoWork با بررسی ویژگی CancellationPending متوجه درخواست برای پایان عملیات شده و ویژگی Cancel از ورودی رویداد DoWork را برابر با true قرار داده باشید.
ویژگیها
CancellationPending
مشخص می کند که آیا هیچ درخواستی برای قطع عملیات شده است یا نه.
مقدار این ویژگی با فراخوانی تابع CancelAsync به true تغییر میکند.
IsBusy
مشخص می کند که پروسه در حال اجرا است یا نه. اجرای پروسه با فراخوانی تابع RunWorkerAsync اجرا می شود.
WorkerReportsProgress
مشخص می کند که امکان ارسال وضعیت پیشرفت پروسه وجود دارد به نه. این مقدار برای استفاده از تابع ReportProgress لازم است.
WorkerSupportsCancellation
تعیین می کند آیا امکان استفاده از لغو ادامه عملیات در حین اجرا توسط تابع CancelAsync وجود دارد یا نه.
چند مثال
کاربرد CancellationPending و ReportProgress در رویداد DoWork
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i < 10000; i++)
{
if (backgroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
if (i % 1500 == 0)
backgroundWorker.ReportProgress(i);
}
e.Result = "Finished!";
}
کاربرد رویداد RunWorkerCompleted
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
MessageBox.Show("Cancelled");
else if (e.Error != null)
MessageBox.Show(e.Error.Message);
else
MessageBox.Show(e.Result.ToString());
}
مثال کاملی از ویژگی های این کلاس به این مقاله ضمیمه شده است که می توانید دریافت کنید.