Sizin için bir şeyler yapan bir nesnenin varsayımsal bir yöntemini düşünün :
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
Bir BackgroundWorker'ın yapılması için nasıl beklenebilir?
Geçmişte insanlar denedi:
while (_worker.IsBusy)
{
Sleep(100);
}
Ancak bu kilitlenir , çünkü olay IsBusy
işlenene kadar temizlenmez RunWorkerCompleted
ve bu olay uygulama boşta kalana kadar işlenemez. İşçi bitene kadar uygulama boşta kalmayacaktır. (Ayrıca yoğun bir döngü - iğrenç.)
Diğerleri, içeriğin klud edilmesini önerdi:
while (_worker.IsBusy)
{
Application.DoEvents();
}
Bununla ilgili sorun, Application.DoEvents()
şu anda kuyrukta olan mesajların işlenmesine neden olarak yeniden giriş sorunlarına neden olmasıdır (.NET yeniden giriş değildir).
Kodun bulunduğu, Olay senkronizasyon nesnelerini içeren bir çözüm kullanmayı umuyorum. , çalışanın RunWorkerCompleted
olay işleyicilerinin ayarladığı bir olayı beklediği . Gibi bir şey:
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
_workerDoneEvent.SetEvent();
}
Ancak çıkmaza geri döndüm: olay işleyicisi, uygulama boşta kalana kadar çalışamaz ve uygulama bir Olayı beklediği için boşta kalmaz.
Peki, bir BackgroundWorker'ın bitirmesini nasıl bekleyebilirsiniz?
Güncelleme İnsanların bu soruyla kafası karışmış görünüyor. BackgroundWorker'ı şu şekilde kullanacağımı düşünüyorlar:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
Yani değil olduğunu, bu değil ben ne yaptığımı ve olmasıdır değil burada ne soruluyor. Durum böyle olsaydı, bir arka plan çalışanı kullanmanın bir anlamı olmazdı.