使用WaitHandle.WaitOne

时间:2015-02-04 18:12:03

标签: c# multithreading asynchronous task waithandle

我正在尝试创建一个Windows服务,每5分钟轮询一个系统并检查一些需要完成的操作。我已经阅读了WaitHandles及其在这方面的用处,但需要了解其工作原理。

见下面的代码:

public partial class PollingService : ServiceBase
{
    private CancellationTokenSource cancelToken = new CancellationTokenSource();
    private Task mainTask = null;
    public PollingService()
    {
        InitializeComponent();  
    }
    protected override void OnStart(string[] args)
    {   
        mainTask = new Task(pollInterval, cancelToken.Token, TaskCreationOptions.LongRunning);
        mainTask.Start();
    }
    public void pollInterval()
    {
        CancellationToken cancel = cancelToken.Token;
        TimeSpan interval = TimeSpan.FromMinutes(5);
        while (!cancel.IsCancellationRequested && !cancel.WaitHandle.WaitOne(interval))
        {
            if (cancel.IsCancellationRequested)
            {
                break;
            }
            EventLog.WriteEntry("*-HEY MAN I'M POLLNG HERE!!-*");
            //Polling code goes here. Checks periodically IsCancellationRequested
        }
    }
    protected override void OnStop()
    {
        cancelToken.Cancel();
        mainTask.Wait();
    }
}

以上代码似乎应该适用于我的研究,但我不理解!cancel.WaitHandle.WaitOne(interval)部分。这是如何通过每五分钟等待来保持循环的?我需要理解这部分代码来完成我的脚本,或者知道我在使用WaitHandle时是否完全错误。

这就是我的想法:Creating a c# windows service to poll a database

1 个答案:

答案 0 :(得分:1)

正如Hans所指出的那样解释,这里的用法是让线程等待一段特定的时间,但仍然允许线程在超时时间到期之前被唤醒,例如,如果您需要提前终止线程(如此处)。

那就是说,这个实施是"旧学校"。 :)如果您使用的是.NET 4.5,如果您使用async / await惯用语(特别是因为您已经使用CancellationTokenSource),恕我直言的代码会更好用: / p>

    protected async override void OnStart(string[] args)
    {   
        try
        {
            await pollInterval();
        }
        catch (TaskCanceledException) { }
    }

    public async Task pollInterval()
    {
        CancellationToken cancel = cancelToken.Token;
        TimeSpan interval = TimeSpan.FromMinutes(5);
        while (true)
        {
            await Task.Delay(interval, cancel);
            EventLog.WriteEntry("*-HEY MAN I\"M POLLNG HERE!!-*");
            //Polling code goes here. Checks periodically IsCancellationRequested
        }
    }

通过上述,代码更正确地表达了意图。也就是说,虽然WaitHandle版本似乎主要是等待发信号退出,但即使工作中的主要机制实际上是等待的超时,这里代码清楚地表明主要意图是延迟,有可能延迟被取消。