使用TPL创建阻塞方法调用的超时

时间:2011-07-07 16:42:04

标签: c# .net imap task-parallel-library cancellationtokensource

我有一个阻塞库调用,一个imap Idle,它将在一个长时间运行的服务中等待电子邮件,我很偏执,不相信图书馆永远不会错过任何电子邮件。可以通过并发调用StopIdle来取消空闲调用。如果它认为它仍处于空闲状态,我会按照以下方式调用StopIdle。

有更好的方法来执行以下操作吗?这种方法有效,但似乎我最终会占用一堆刚刚睡觉的线程池线程。

while (true)
{
    // read unseen emails here ...

    var cancelSource = new CancellationTokenSource();
    var cancelToken = cancelSource.Token;

    Task stopIdleOccasionally = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(TimeSpan.FromMinutes(1));

            if (cancelToken.IsCancellationRequested)
            {
                return;
            }

            client.StopIdle(); // This causes the Idle() call to return
        },
        cancelSource.Token);

    client.Idle(); // This is the blocking call that I want to create a timeout for
    cancelSource.Cancel();
}

1 个答案:

答案 0 :(得分:1)

使用Henk的建议我用计时器重写了它:

Timer stopIdleTimeoutTimer = new Timer(
    _ => client.StopIdle(),
    null,
    TimeSpan.FromMinutes(1),
    TimeSpan.FromMilliseconds(-1));

client.Idle();

stopIdleTimeoutTimer.Dispose();

由于我的库无法访问代码,因此无法改变Idle方法的行为