繁体   English   中英

取消令牌和线程不起作用

[英]Cancellation token and thread not working

我想取消一个线程,然后立即运行另一个线程。 这是我的代码:

private void ResetMedia(object sender, RoutedEventArgs e)
{
        cancelWaveForm.Cancel(); // cancel the running thread
        cancelWaveForm.Token.WaitHandle.WaitOne(); // wait the end of the cancellation
        cancelWaveForm.Dispose();

        //some work

        cancelWaveForm = new CancellationTokenSource(); // creating a new cancellation token
        new Thread(() => WaveFormLoop(cancelWaveForm.Token)).Start(); // starting a new thread
}

当我调用此方法时,第一个线程不会停止,第二个线程开始运行...
但是,如果我跳过最后两行,它将起作用:

private void ResetMedia(object sender, RoutedEventArgs e)
{
        cancelWaveForm.Cancel(); // cancel the running thread
        cancelWaveForm.Token.WaitHandle.WaitOne(); // wait the end of the cancellation
        cancelWaveForm.Dispose();

        //some work

        //cancelWaveForm = new CancellationTokenSource(); // creating a new cancellation token
        //new Thread(() => WaveFormLoop(cancelWaveForm.Token)).Start(); // starting a new thread
}

为什么不停止?

编辑1:

private void WaveFormLoop(CancellationToken cancelToken)
{
        try
        {
            cancelToken.ThrowIfCancellationRequested();
            //some stuff to draw a waveform
        }
        catch (OperationCanceledException) 
        {
            //Draw intitial Waveform
            ResetWaveForm();
        }
}

使用CancellationTokens称为“合作取消”,因为代码必须与取消动作合作。 您仅在函数启动时检查一次,如果取消在该检查之后发生,则取消永远不会发生。

基于函数的名称,我假设其中存在某种循环。 您的函数需要看起来像这样。

private void WaveFormLoop(CancellationToken cancelToken)
{
        try
        {
            while(someCondition) //Replace this with your real loop structure, I had to guess
            {
                cancelToken.ThrowIfCancellationRequested();
                //some stuff to draw a waveform
            }
        }
        catch (OperationCanceledException) 
        {
            //Draw intitial Waveform
            ResetWaveForm();
        }
}

现在,它检查循环的每次迭代是否都发生取消。 如果循环主体需要很长时间才能处理,则您可能希望在循环内部进行多个调用。

private void WaveFormLoop(CancellationToken cancelToken)
{
        try
        {
            while(someCondition) //Replace this with your real loop structure, I had to guess
            {
                cancelToken.ThrowIfCancellationRequested();

                Thread.Sleep(1000); //Fake doing work

                cancelToken.ThrowIfCancellationRequested();

                Thread.Sleep(1000); //Fake doing more work
            }
        }
        catch (OperationCanceledException) 
        {
            //Draw intitial Waveform
            ResetWaveForm();
        }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM