【问题标题】:CancellationToken Cancel not breaking out of BlockingCollectionCancellationToken 取消不脱离 BlockingCollection
【发布时间】:2014-04-03 17:22:07
【问题描述】:

我有一个这样的取消令牌

   static CancellationTokenSource TokenSource= new CancellationTokenSource();

我有一个像这样的阻塞集合

BlockingCollection<object> items= new BlockingCollection<object>();

var item = items.Take(TokenSource.Token);

if(TokenSource.CancelPending)
   return;

当我打电话时

TokenSource.Cancel();

Take 没有像它应该的那样继续。如果我将 TryTake 与投票一起使用,则 Token 显示它被设置为 Canceled。

【问题讨论】:

    标签: c# collections parallel-processing cancellation-token


    【解决方案1】:

    按预期工作。如果操作被取消,items.Take 将抛出OperationCanceledException。这段代码说明了这一点:

    static void DoIt()
    {
        BlockingCollection<int> items = new BlockingCollection<int>();
        CancellationTokenSource src = new CancellationTokenSource();
        ThreadPool.QueueUserWorkItem((s) =>
            {
                Console.WriteLine("Thread started. Waiting for item or cancel.");
                try
                {
                    var x = items.Take(src.Token);
                    Console.WriteLine("Take operation successful.");
                }
                catch (OperationCanceledException)
                {
                    Console.WriteLine("Take operation was canceled. IsCancellationRequested={0}", src.IsCancellationRequested);
                }
            });
        Console.WriteLine("Press ENTER to cancel wait.");
        Console.ReadLine();
        src.Cancel(false);
        Console.WriteLine("Cancel sent. Press Enter when done.");
        Console.ReadLine();
    }
    

    【讨论】:

    • 只有我一个人,还是这个“异常驱动开发”的概念很奇怪?没有什么反对吉姆的回答,这正是微软实施它的方式。但是我想取消一个操作也不例外,不是吗?我错过了一个只会返回 false 的重载 - 类似于那些超时重载。
    猜你喜欢
    • 2016-03-08
    • 2015-09-01
    • 2018-06-06
    • 2016-02-24
    • 1970-01-01
    • 2017-01-29
    • 2012-12-01
    • 2012-02-24
    • 2019-03-09
    相关资源
    最近更新 更多