中止线程(Backgroundworker)..需要一个建议

时间:2011-07-21 16:12:29

标签: c# winforms multithreading backgroundworker

        public void ReplayGame()
    {

        if (Class2.replayIsOn)
        {

            if (!backgroundWorker1.IsBusy)
            {
                backgroundWorker1.RunWorkerAsync();
            }
        }                 
    }

我想在函数结束时取消/停止backgroundwoker1 .. backgroundworker事件运行几秒钟然后停止..当它停止时我希望它结束​​!! ..

我怎样才能完成这项任务?没有得到我现在得到的任何无效操作异常

更新:

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

5 个答案:

答案 0 :(得分:3)

您是否检查过工人支持取消?

backgroundWorker1.WorkerSupportsCancellation = true;

如果您没有明确设置,请致电

backgroundWorker1.CancelAsync();
将抛出

InvalidOperationException ,因为默认情况下,worker不支持异步取消。

<强>更新
这只是检查工人状态的属性,如果你需要取消你需要拨打的工作backgroundWorker1.CancelAsync();

查看示例here

答案 1 :(得分:2)

您只是在开始循环之前检查取消是否等待一次,然后再也不检查。您需要通过循环检查每次迭代:

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

答案 2 :(得分:1)

我想指出:

if (backgroundWorker1.IsBusy)              
{                    
backgroundWorker1.CancelAsync();              
}                
if (!backgroundWorker1.IsBusy)              
{
replay = serializeMeh.giveBackDictionary();                  backgroundWorker1.RunWorkerAsync();              
}  

真的应该是:

if (backgroundWorker1.IsBusy)              
{                    
backgroundWorker1.CancelAsync();              
}                
else
{
replay = serializeMeh.giveBackDictionary();                  backgroundWorker1.RunWorkerAsync();              
}

答案 3 :(得分:0)

首先,您需要致电CancelAsync。然后,您需要使用带有CancellationPending声明的guard clause检查return媒体资源。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // A bunch of stuff here.

    if (backgroundWorker1.CancellationPending) return;

    // A bunch of stuff here.
}

答案 4 :(得分:0)

在我看来,在DoWork回调结束时取消BackgroundWorker是不必要的?按照设计,BackgroundWorker在DoWork回调退出时会停止工作;此时,RunWorkerCompleted事件就像调用CancelAsync()之后一样被提出。

除非我在原始问题中遗漏了某些内容,否则我不会看到默认行为有何不同以及为什么取消该工作人员是首选?