Закрытие формы, когда backgroundWorker перестает работать

Я работаю над приложением, которое должно читать данные с смарт-карты Mifare. Я должен создать форму, которая будет проверять считыватель Mifare периодически и когда карта находится в зоне действия, прочитайте ее серийный номер и отправьте его в родительскую форму. Мне удалось заставить фонового работника прочитать серийный номер, но я не могу закрыть форму из-за ошибки перекрестного потока, которую это вызвало бы. Есть ли способ контролировать работу, выполняемую backGroundWorker, и когда она успешно считывает идентификатор карты, чтобы остановить ее и закрыть дочернюю форму? Это код, который я использую в методе DoWork:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
 BackgroundWorker worker = sender as BackgroundWorker;
 while (!worker.CancellationPending)
 {
 MifareReader.CommPort = 4;
 MifareReader.PortOpen = true;
 MifareReader.mfAutoMode(true); 
 MifareReader.mfRequest(); 
 if (CardID == "0" || CardID == string.Empty)
 {
 MifareReader.mfRequest();
 CardID = MifareReader.mfAnticollision().ToString();
 MifareReader.mfHalt();
 }
 else if (CardID != "0" && CardID != string.Empty)
 {
 MessageBox.Show(ObrnutiID);
 worker.CancelAsync(); 
 }
 MifareCitac.mfHalt();
 }
}

Этот код выполняет эту работу, но мне нужно вручную закрыть форму. Есть ли способ проверить, изменит ли переменная CardID ее значение в основном потоке, и если это произойдет, закройте форму. Я попытался решить эту проблему, используя таймер, но когда я это делаю, таймер блокирует поток основной формы, и я не могу закрыть его вручную (что, конечно, я должен быть способен). Можете ли вы предложить способ решить эту проблему?

5 ответов

Вы можете использовать событие BackgroundWorker.RunWorkerCompleted для мониторинга при выполнении BackgroundWorker.

Происходит при завершении фоновой операции, отменяется или возникает исключение.

Оттуда вы можете закрыть форму программно.


Вы можете написать BackgroundWorker, чтобы он возвращался, когда он закончил свою работу.

Затем в вашей основной форме подпишитесь на BackgroundWorker.RunWorkerCompleted и ответьте соответствующим образом, предположительно, просто закрыв форму.


Вы можете избежать ошибок при перекрестном потоке, проверив InvokedRequired и попробуйте BeginInvoke с помощью делегатов.


Добавьте RunWorkerCompleted событие из вашего фона.

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
 this.Close() // Closes the form.
}


Как уже упоминалось, вот как реализовать событие BackgroundWorker.RunWorkerCompleted:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
 bool found = false;
 var worker = sender as BackgroundWorker;
 while (!worker.CancellationPending && !found)
 {
 MifareReader.CommPort = 4;
 MifareReader.PortOpen = true;
 MifareReader.mfAutoMode(true); 
 MifareReader.mfRequest(); 
 if (CardID == "0" || CardID == string.Empty)
 {
 MifareReader.mfRequest();
 CardID = MifareReader.mfAnticollision().ToString();
 MifareReader.mfHalt();
 }
 else
 {
 e.Result = ObrnutiID;
 found = true;
 MifareCitac.mfHalt();
 }
 }
 if (worker.CancellationPending)
 {
 e.Cancel = true;
 }
}
 private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
 {
 if (e.Cancelled)
 {
 // The user canceled the operation.
 MessageBox.Show("Operation was canceled");
 }
 else if (e.Error != null)
 {
 // There was an error during the operation. 
 string msg = String.Format("An error occurred: {0}", e.Error.Message);
 MessageBox.Show(msg);
 }
 else
 {
 // The operation completed normally. 
 string msg = String.Format("Result = {0}", e.Result);
 MessageBox.Show(msg);
 }
 this.Close() // Closes the form.
 }

licensed under cc by-sa 3.0 with attribution.