Closing a form when backgroundWorker stops working

I am working on an application that should read data from a Mifare smart card. I have to create a form that will check the Mifare reader periodically and when the card is in range, read its serial number and send it to the parent form. I managed to get the background worker to read the serial number, but I cannot close the form due to the cross-flow error that this would cause. Is there a way to control the work that backGroundWorker is doing and when it successfully reads the card id to stop it and close the child form? This is the code I'm using in the DoWork method:

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(); } } 

This code does the job, but I need to manually close the form. Is there a way to check if the CardID variable will change its value in the main thread, and if that happens, close the form. I tried to solve this problem using a timer, but when I do this, the timer blocks the flow of the main form and I cannot close it manually (which, of course, I should be able to). Can you suggest a way to solve this problem?

+4
source share
6 answers

You can use the BackgroundWorker.RunWorkerCompleted event to monitor when BackgroundWorker is running.

Occurs when the background operation completes, is canceled, or an exception is thrown.

From there, you can close the form programmatically.

+4
source

You can write BackgroundWorker to return when it has finished its work.

Then, in your main form, subscribe to BackgroundWorker.RunWorkerCompleted and respond accordingly, presumably by simply closing the form.

+3
source

Add a RunWorkerCompleted event from your background.

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

You can avoid cross-threading errors by checking InvokedRequired and trying BeginInvoke with delegates.

+1
source

As already mentioned, here's how to implement the BackgroundWorker.RunWorkerCompleted event:

 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. } 
+1
source

I wrote the code as shown below. But still I get the same error "operation with multiple threads is not valid"

 Intermediate_Form form = new Intermediate_Form(); private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { form.Close(); MessageBox.Show(e.Result.ToString()); } 
0
source

Source: https://habr.com/ru/post/1482931/


All Articles