C#协作试取消线程

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace 取消线程池中线程
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine( "主线程运行" );
            CancellationTokenSource cts = new CancellationTokenSource(  );
            //ThreadPool.QueueUserWorkItem(CallBack, cts.Token );
            ThreadPool.QueueUserWorkItem(CallBack, cts);
            Console.WriteLine(  "按下回车键取消启动的线程" );
            Console.Read(  );
            cts.Cancel();
            Console.ReadKey();
        }

        public static void CallBack( object state )
        {
            CancellationTokenSource cts = (CancellationTokenSource)state;
            Console.WriteLine( "开始计数" );
            Count( cts, 5 );
        }
        private static void Count(CancellationTokenSource cts, int countto )
        {
            for( int i=0; i<=countto+10; ++i) {
                if( i== countto) {
                    cts.Cancel();
                    Console.WriteLine( "计算取消" );
                    //return;
                }
                Console.WriteLine( "计算为:{0}, 当前线程ID: {1}", i, Thread.CurrentThread.ManagedThreadId );
                Thread.Sleep(300);
            }
            Console.WriteLine("计数完成");
        }
    }
}

clipboard.png

很明显在调用cts.Cancel()后Count()函数还在执行,看到书上说CancellationTokenSource是协助式取消线程,刚学多线程,很多不明白的。
我们将一些任务(函数)放在某一个线程中执行,如果任务终止是不是就代表线程取消了
上述代码如果改为:

if( i== countto) {
    cts.Cancel();
    Console.WriteLine( "计算取消" );
    return;
}

这样是不是就可以正确的取消线程。

阅读 2.2k
1 个回答

Count 方法中需要使用 cts.IsCancellationRequested 来判断当前线程是否已经被取消。

if (cts.IsCancellationRequested)
{
    Console.WriteLine( "计算取消" );
    return;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进