取消令牌和线程无法正常工作

Bog*_*ogy 0 c# multithreading cancellationtokensource cancellation-token

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

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
}
Run Code Online (Sandbox Code Playgroud)

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

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
}
Run Code Online (Sandbox Code Playgroud)

为什么不停止?

编辑1:

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

Sco*_*ain 7

使用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();
        }
}
Run Code Online (Sandbox Code Playgroud)

现在它检查循环的每次迭代是否发生了取消.如果循环体需要很长时间来处理,则可能需要在循环内调用多个.

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();
        }
}
Run Code Online (Sandbox Code Playgroud)