【问题标题】:Sleep .NET Task, Wake on CancellationTokenSource.Cancel()睡眠 .NET 任务,唤醒 CancellationTokenSource.Cancel()
【发布时间】:2012-10-01 21:29:08
【问题描述】:

我的代码必须定期轮询外部资源。简化后看起来像:

CancellationTokenSource cancellationSource = new CancellationTokenSource();

Task t = Task.Factory.StartNew(() =>
    {
        while (!cancellationSource.IsCancellationRequested)
        {
            Console.WriteLine("Fairly complex polling logic here.");

            // Finishes sleeping before checking for cancellation request
            Thread.Sleep(10000); 
        }
    },
    cancellationSource.Token);

如何以这样一种方式对 10 秒的延迟进行编码,以便在调用 cancelSource.Cancel() 时将其中断?

【问题讨论】:

    标签: .net multithreading


    【解决方案1】:

    如何使用超时为 10 秒的监视器。您可以使用 Monitor 类的 Pulse 方法唤醒正在休眠的线程

    线程 1:

    Monitor.Wait(monitor, 10000);
    

    线程 2:

    Monitor.Pulse(monitor);
    

    或者您可以查看ManualResetEvent.WaitOne。用 10 秒超时阻塞线程。要取消阻止,请发出事件信号。

    编辑:

    CancellationToken 有一个 .WaitHandle 属性:

    获取在取消令牌时发出信号的 WaitHandle。

    您可以等待该句柄发出信号,超时 10 秒?

    【讨论】:

    • 这可能行得通,但似乎......错误......需要第二个线程来脉冲第一个线程,只是为了获得可中断的睡眠。
    • 但是如果线程睡着了,我看不到它是如何被唤醒的,除非从另一个线程。一个丑陋的方法是让它更细化。一个循环进行较小的睡眠,检查取消布尔值。从 CPU 的角度来看,问题并不理想。
    • 从概念上讲,如果取消令牌被取消,线程调度程序可以中断对任何延迟/等待的调用。不确定这是否可以实际完成。
    • 完美!那行得通。 cancellationSource.Token.WaitHandle.WaitOne(10000);
    猜你喜欢
    • 2012-10-08
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多