PDA

View Full Version : چرا نمیشه یه backgroundWorker با وجود این که کنسل شده رو دباره اجرا کرد؟



hamedre81
شنبه 12 بهمن 1392, 11:45 صبح
سلام دوستان

من یه backgroundWorker دارم یه سری کار می کنه
می خوام موقع کار این backgroundWorker اون رو کنسل می کنم و با شرایط جدید دباره اجرا کنم

اما موقع اجرا دباره این خطا میده
This BackgroundWorker is currently busy and cannot run multiple tasks concurrently.

من که این backgroundWorker رو کنسل کردم چرا این خطا رو می ده ؟
:چشمک:

plus
شنبه 12 بهمن 1392, 16:57 عصر
عملیات Cancel کردن در BackgroundWorker خودکار نیست.یعنی اینکه شما باید در رویداد DoWork که عملیات مورد نظر رو دارین انجام میدین، مقدار CancellationPending رو بررسی کنید و در صورت True بودن، عملیات رو ادامه ندین...بنابراین عملیات Cancel کردن، اول باید توسط شما پیاده سازی بشه و دوم اینکه لزوما همزمان نیست.

private void button1_Click(object sender, EventArgs e)
{
backgroundWorker.CancelAsync();
}

void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{
// Do something...

if (backgroundWorker.CancellationPending)
{
e.Cancel = true;
break;
}
}
}

void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
MessageBox.Show("Operation was cancelled!");
else
MessageBox.Show("Operation Completed!");
}

fmehrvarzi
شنبه 12 بهمن 1392, 18:45 عصر
سلام دوستان

من یه backgroundWorker دارم یه سری کار می کنه
می خوام موقع کار این backgroundWorker اون رو کنسل می کنم و با شرایط جدید دباره اجرا کنم

اما موقع اجرا دباره این خطا میده
This BackgroundWorker is currently busy and cannot run multiple tasks concurrently.

من که این backgroundWorker رو کنسل کردم چرا این خطا رو می ده ؟
:چشمک:
این خطا به خاطر این رخ داده است که بکگراندوورکر شما کنسل نشده است و شما دوباره آنرا میخواهید اجرا کنید
برای اطمینان از دوباره اجرا نشدن بک گراندوورکر این کد را
worker.RunWorkerAsync();
با این کد جایگزین کنید:
if( !worker.IsBusy )
worker.RunWorkerAsync();
else
MessageBox.Show("Can't run the worker twice!");
منبع:
http://stackoverflow.com/questions/588150/this-backgroundworker-is-currently-busy-and-cannot-run-multiple-tasks-concurrent

سوال دیگه ای؟ اگر میتوانید یک کد ضمیمه کنید

hamedre81
شنبه 12 بهمن 1392, 20:47 عصر
سلام دوستان
طبق گفته plus (http://barnamenevis.org/member.php?8256-plus) من نمی تونم BackgroundWorker رو متوقف کنم چون BackgroundWorker فقط یه تابع اجرا می کنه و کار ها درون اون برنامه انجام می دن کنسل شدن

این theard رو من نوشتم اما چطوری می تونم از تمام شدن theardخبر شم؟
از ThreadState با یه تایمر میشه چک کرد اما راه بهتری نیست؟

Thread t = new Thread(Startup);

fmehrvarzi
یک شنبه 13 بهمن 1392, 04:32 صبح
سلام دوستان
طبق گفته plus (http://barnamenevis.org/member.php?8256-plus) من نمی تونم BackgroundWorker رو متوقف کنم چون BackgroundWorker فقط یه تابع اجرا می کنه و کار ها درون اون برنامه انجام می دن کنسل شدن

این theard رو من نوشتم اما چطوری می تونم از تمام شدن theardخبر شم؟
از ThreadState با یه تایمر میشه چک کرد اما راه بهتری نیست؟

Thread t = new Thread(Startup);


از طریق دستور worker.IsBusy میتوانید بفهمید که تمام شده یا نه
و یا میتوhنید در رویداد RunWorkerCompleted بکگراندوورکرتان بعد از اتمام کارش دستورات دیگری را در نخ اصلی Main Thread اجرا کنید.
worker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(worker_RunWorkerCom pleted);

برای اطلاعات بیشتر: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

plus
یک شنبه 13 بهمن 1392, 08:44 صبح
سلام دوستان
طبق گفته plus (http://barnamenevis.org/member.php?8256-plus) من نمی تونم BackgroundWorker رو متوقف کنم چون BackgroundWorker فقط یه تابع اجرا می کنه و کار ها درون اون برنامه انجام می دن کنسل شدن

این theard رو من نوشتم اما چطوری می تونم از تمام شدن theardخبر شم؟
از ThreadState با یه تایمر میشه چک کرد اما راه بهتری نیست؟

Thread t = new Thread(Startup);



اگه در UI Thread بخواین بفهمین که چه موقع Thread تموم شده، بایستی آخر کدی که در Thread اجرا میشه با استفاده از متد Invoke فرم، اون رو با خبر کنید.:


private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(MyMethod));
thread.Start();
}
void MyMethod()
{
// Do something ...
this.Invoke((MethodInvoker)delegate { Done(); });
}

private void Done()
{
MessageBox.Show("Done!");
}

البته شما با استفاده از متد Join یک Thread میتونید Thread جاری رو تا زمان اتمام اون Thread متوقف کنید ولی خوب اگه Thread جاری شما UI Thread باشه این کار باعث هنگ کردن UI میشه.