PDA

View Full Version : مشکل با backgroundWorker



hamid67fathi
شنبه 13 تیر 1388, 10:41 صبح
سلام
من با استفاده از backgroundworker يه ديتا تيبل سنگين رو پر ميکنم.
اما نميتونم موقعيت cancel بودن رو چک کنم .
کسی راه حلی داره ؟

Sajjad.Aghapour
شنبه 13 تیر 1388, 22:27 عصر
می تونید از خاصیت BGWorker.CancellationPending استفاده کنید....

hamid67fathi
شنبه 13 تیر 1388, 22:44 عصر
سلام
اين مورد در صورتی پاسخ گو هست که ترد مشغول نباشه و هر لحظه امکان چک کردن اين ويژگی وجود داشته باشه.
اما زمانی که ديتا تيبل در حال پر شدن هست اين امکان وجود نداره.

Sajjad.Aghapour
شنبه 13 تیر 1388, 23:04 عصر
خوب بله.اصولا شرط IsBusy هم چک میشه...


if(BGWorker.IsBusy)
{
BGWorker.CancelAsync();
this.Text="cancelling operation....";
}

hamid67fathi
شنبه 13 تیر 1388, 23:51 عصر
سلام
امکانش هست يک مثال بزنيد ؟
من امتحان کردم ولی جوابی نگرفتم .

Sajjad.Aghapour
یک شنبه 14 تیر 1388, 09:20 صبح
private void button_Click(object sender, EventArgs e)
{
if (bgWorker.IsBusy)
bgWorker.CancelAsync();
}

//

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (bgWorker.CancellationPending)
{
e.Cancel = true;
return;
}
}

//

private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
this.Text = "cancelled";
}

hamid67fathi
یک شنبه 14 تیر 1388, 09:49 صبح
private void button_Click(object sender, EventArgs e)
{
if (bgWorker.IsBusy)
bgWorker.CancelAsync();
}

//

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
// اينجا ديتا تيبل پر شود
if (bgWorker.CancellationPending)
{
e.Cancel = true;
return;
}
}

//

private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
this.Text = "cancelled";
}

حالا اگر طبق کد بالا عمل کنيم برنامه به خط پر کردن ديتا تيبل ميرسه و مدتی طول ميکشه !
حالا اگر در همين مدت کاربر درخواست Cancel داشته باشه ، چی ؟

__H2__
یک شنبه 14 تیر 1388, 18:16 عصر
سلام
یک راه سریع برای توقف هر ریسمانی وجود دارد که البته آخرین راه حل باید باشد!
متد Abort



private System.Threading.Thread m_Thread;

private void button_Click(object sender, EventArgs e)
{
System.Threading.Thread thread = this.m_Thread;
if (thread != null)
{
try
{
thread.Abort();
}
catch { }
}
}

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
this.Thread = System.Threading.Thread.CurrentThread;
//...
//anu code...
//...
this.Thread = null;
}

private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Thread = null;
//...
//anu code...
//...
}


موفق باشید.

hamid67fathi
یک شنبه 14 تیر 1388, 23:24 عصر
سلام
ممنون که راهنمايی ميکنيد !
امکانش هست که توضيحی در مورد نحوه کار کرد کد بديد ؟

__H2__
دوشنبه 15 تیر 1388, 12:31 عصر
سلام
توضیح خاص و پیچیده ای ندارد ...
هر ریسمان در دات نت یک کلاس دارد.
با شروع ریسمان جدید در قالب backgroundWorker و رویداد bgWorker_DoWork کلاس ریسمان را بدست آورده و در متغییری ذخیره میکنیم...
در پایان کار ریسمان هم این متغییر را خالی میکنیم.

سپس در متد لغو عملیات یا همان cancel اگر متغییر ریسمان خالی نباشد متد Abort را برای توقف سریع ریسمان اجرا میکنیم. (یک چیز تو مایه های EndTask !) کدهای اجرایی درون آن ریسمان در هر جایی باشند با خطای ThreadAbortException متوقف میشود.
(اون متغییر محلی داخل button_Click اضافی نیست و بهتر است بگذارید بماند!)

موفق باشید.