I have a BackgroundWorker_DoWork
method in my client application which sends a tcp message using NetworkComms.Net to a server and check for an answer.
The method for that last part is
NetworkComms.AppendGlobalIncomingPacketHandler
where I can verify if the answer has a certain type and if yes, invoke another method to handle the answer message itself.
What I want to do is to stop the BackgroundWorker from within the handler, but I can't figure out how. Any help is greatly appreciated, as I'm very new to Object-Oriented Programming and I'm probably missing something fundamental.
Here's the relevant piece of code:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
if (backgroundWorker2.CancellationPending)
{
e.Cancel = true;
return;
}
string serverIP = entr_serverIP.Text;
int serverPORT;
int.TryParse(entr_serverPORT.Text, out serverPORT);
bool loop = true;
while (loop == true)
{
if (backgroundWorker2.CancellationPending)
{
e.Cancel = true;
return;
}
try
{
NetworkComms.SendObject("Message", serverIP, serverPORT, "status");
NetworkComms.AppendGlobalIncomingPacketHandler<string>("ReturnHere", DoSomething2);
}
catch(DPSBase.CommsException ex2)
{
MessageBox.Show(ex2.ToString());
e.Cancel = true;
return;
}
Thread.Sleep(100);
}
}
private static void DoSomething2(PacketHeader header, Connection connection, string message)
{
bool svAlarmSent = false;
while (svAlarmSent == false)
{
if (message == "KEYWORD")
{
string svInfo = connection.ConnectionInfo.RemoteEndPoint.ToString();
Form4 form4 = new Form4("KEYWORD", null, svInfo);
form4.Show();
svAlarmSent = true;
backgroundWorker2.CancelAsync();
loop = false;
}
}
}
The two last lines of the above code don't work because the CancelAsync
method and the loop
variable don't exist in that context.
The first step to fixing this is to enable cancellation from the DoSomething2
method. To do this it needs access to the backgroundWorker2
variable. This is a field (attribute), hence you can give it access by making the method non-static:
private void DoSomething2(PacketHeader header, Connection connection, string message)
The next step is to simple remove the access of the loop
value from DoSomething2
. The responsibility of this method is to signal the cancellation only. It is the job of the backgroundWorker2_DoWork
method to respond to this cancellation.
In fact the loop
variable doesn't even need to be set. Once CancelAsync
is called the following conditional will be met:
if (backgroundWorker2.CancellationPending)
{
e.Cancel = true;
return;
}
By virtue of returning this code will break the while
loop by itself.
Overall I would say that this isn't really the intended use of a BackgroundWorker
though. Cancellation is supposed to be used to allow the user, or some operation, to signal that the background task should cancel the work and return without completing (if possible). In this case you are using cancellation to signal the succesful completion of the code. This works but is somewhat of an unintended use case.