Reputation: 7053
public void ReplayGame()
{
if (Class2.replayIsOn)
{
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync();
}
}
}
I wan to cancel/stop backgroundwoker1 as soon as the function ends.. the backgroundworker event runs for a few seconds and stops..when it stops I want it to end!!..
How can I achieve that task/? without getting any invalid operation exceptions that i am getting now
UPDATE:
public void ReplayGame()
{
if (Class2.replayIsOn)
{
replay = serializeMeh.giveBackDictionary();
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.RunWorkerAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int[] makeSelfMoves = new int[4];
if (!backgroundWorker1.CancellationPending)
{
lock (replay)
{
foreach (KeyValuePair<int, int[]> item in replay)// count should be more than 2
{
if (backgroundWorker1.CancellationPending)
{
break;
}
makeSelfMoves = replay[item.Key];
codeFile.ExecuteAll(makeSelfMoves[0], makeSelfMoves[1], makeSelfMoves[2], makeSelfMoves[3]);
PrintPieces(codeFile.PieceState()); Invalid operation exception is thrown here when chess pieces are drawn on the screen ... Two threads enter the loop simultaneously..:(...Invalid operation exception
System.Threading.Thread.Sleep(1000);
}
Class2.counter = serializeMeh.serializedCounter;
Class2.replayIsOn = false;
Game.WasntSerialized = true;
}
}
backgroundWorker1.CancelAsync();
}
Upvotes: 1
Views: 2614
Reputation: 7517
It seems to me that cancelling the BackgroundWorker
at the end of the DoWork callback is unnecessary? By design, the BackgroundWorker
does stop working when the DoWork callback exits; at this point the RunWorkerCompleted
event is raised just like it would be after calling CancelAsync()
.
Unless I'm missing something in the original question, I don't see how the default behavior is any different and why cancelling the worker would be preferred?
Upvotes: 0
Reputation: 2551
I would like to point out that:
if (backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
}
if (!backgroundWorker1.IsBusy)
{
replay = serializeMeh.giveBackDictionary(); backgroundWorker1.RunWorkerAsync();
}
really should be:
if (backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
}
else
{
replay = serializeMeh.giveBackDictionary(); backgroundWorker1.RunWorkerAsync();
}
Upvotes: 1
Reputation: 21712
You are only checking to see if cancellation is pending once before you start your loop, then never check it again. You need to check every iteration through the loop:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int[] makeSelfMoves = new int[4];
{
lock (replay)
{
foreach (KeyValuePair<int, int[]> item in replay)// count should be more than 2
{
makeSelfMoves = replay[item.Key];
codeFile.ExecuteAll(makeSelfMoves[0], makeSelfMoves[1], makeSelfMoves[2], makeSelfMoves[3]);
PrintPieces(codeFile.PieceState());
if (backgroundWorker1.CancellationPending)
break;
System.Threading.Thread.Sleep(1000);
}
Class2.counter = serializeMeh.serializedCounter;
Class2.replayIsOn = false;
Game.WasntSerialized = true;
}
}
}
Upvotes: 2
Reputation: 48949
First you need to call CancelAsync
. Then you need to check the CancellationPending
property using a guard clause with a return
statement.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// A bunch of stuff here.
if (backgroundWorker1.CancellationPending) return;
// A bunch of stuff here.
}
Upvotes: 0
Reputation: 35905
Did you check that the worker support cancellation?
backgroundWorker1.WorkerSupportsCancellation = true;
If you haven't explicitly set it and you call
backgroundWorker1.CancelAsync();
InvalidOperationException will be thrown, because by default worker doesn't support asynch cancellation.
UPDATE
That's just the property that checks the workers's state, if you need to cancel the work you need to call backgroundWorker1.CancelAsync();
See a sample here
Upvotes: 3