SORU
23 EYLÜL 2008, Salı


Nasıl iptal etmek için bir BackgroundWorker için beklemek?

Bir düşününvarsayımsalsenin için bir şeyler yapan bir nesnenin yöntem:

public class DoesStuff
{
   BackgroundWorker _worker = new BackgroundWorker();

   ...

   public void CancelDoingStuff()
   {
      _worker.CancelAsync();

     //todo: Figure out a way to wait for it to be cancelled
   }
}

Nasıl bir yapılması gereken bir BackgroundWorker bekleyebilir?


Geçmişte başkaları da denedi:

   while (!_worker.IsDone)
   {
      Sleep(100);
   }

Ama this is a deadlock, IsBusy beri RunWorkerCompleted olay işlenme sonrasına kadar temizlenmez ve bu olay uygulama boşta kalıncaya kadar ele almazsınız. Bu uygulama işçi bitene kadar boş gitmeyecek. (Artı, meşgul bir döngü - ve ne kadar iğrenç olduğunu)

Diğerleri ekleyin içine kludging ileri sürmüşlerdir:

   while (!_worker.IsDone)
   {
      Application.DoEvents();
   }

Yeniden entrantcy sorunlara neden olan Application.DoEvents() şu anda kuyruktaki iletileri işlenecek neden olduğu sorun, (.NET içe dönük) değil.

kodu nerede Olay eşitleme nesneleri içeren bir çözüm kullanmak için umarım olurbeklerişçi RunWorkerCompleted bir olay için olay işleyicileri ayarlar. Gibi bir şey

   Event _workerDoneEvent = new WaitHandle();

   public void CancelDoingStuff()
   {
      _worker.CancelAsync();
      _workerDoneEvent.WaitOne();
   }

   private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
   {
      _workerDoneEvent.SetEvent();
   }

Ama kilitlenme için geri döndüm: olay işleyicisi uygulama boşta kalıncaya kadar koşamam, ve uygulama bir Olay bekliyor. çünkü boş gitmeyecek

Nasıl bitirmek için bir BackgroundWorker bekleyebilir misin?


Güncelleme İnsanlar bu soru ile karışık gibi görünüyor. Olarak BackgroundWorker kullanarak olacak sanıyorlar:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork  = MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);

değilbu, odeğilne yaptığımı vedeğilburada ne soruluyor. Eğer öyle olsaydı, arka plan worker (işçi) kullanmanın anlamı olmazdı.

CEVAP
23 EYLÜL 2008, Salı


Eğer gereği eğer doğru anladıysam, böyle bir şey (kodu test değil, ama genel bir fikir gösterir) yapabilirsin:

private BackgroundWorker worker = new BackgroundWorker();
private AutoResetEvent _resetEvent = new AutoResetEvent(false);

public Form1()
{
    InitializeComponent();

    worker.DoWork  = worker_DoWork;
}

public void Cancel()
{
    worker.CancelAsync();
    _resetEvent.WaitOne(); // will block until _resetEvent.Set() call made
}

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    while(!e.Cancel)
    {
        // do something
    }

    _resetEvent.Set(); // signal that worker is done
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Absolute Zero(Programming Tutorials)

    Absolute Zer

    22 Kasım 2012
  • Bart Baker

    Bart Baker

    1 Aralık 2006
  • MrOctopi

    MrOctopi

    6 Aralık 2010