Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为使用TPL阻止方法调用创建超时_C#_.net_Imap_Task Parallel Library_Cancellationtokensource - Fatal编程技术网

C# 为使用TPL阻止方法调用创建超时

C# 为使用TPL阻止方法调用创建超时,c#,.net,imap,task-parallel-library,cancellationtokensource,C#,.net,Imap,Task Parallel Library,Cancellationtokensource,我有一个阻止库调用,一个imap空闲,将在一个长期运行的服务中等待电子邮件,我是偏执狂,不相信库永远不会错过电子邮件。空闲调用可以通过同时调用StopIdle来取消。我实现了以下方法,如果StopIdle认为仍处于空闲状态,则每分钟调用StopIdle 有没有更好的方法来执行以下操作?这个方法是有效的,但看起来我最终会占用一堆线程池线程 while (true) { // read unseen emails here ... var cancelSource = new Ca

我有一个阻止库调用,一个imap空闲,将在一个长期运行的服务中等待电子邮件,我是偏执狂,不相信库永远不会错过电子邮件。空闲调用可以通过同时调用StopIdle来取消。我实现了以下方法,如果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();
}

根据亨克的建议,我用计时器将其改写为:

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

client.Idle();

stopIdleTimeoutTimer.Dispose();

由于它是一个我无法访问代码的库,因此我无法使用Henk的建议更改空闲方法的行为,我使用计时器将其重写为:

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

client.Idle();

stopIdleTimeoutTimer.Dispose();

由于它是一个我无法访问代码的库,因此我无法更改Idle方法的行为

最好使用Idle中的超时或计时器调用StopIdle。如果可以,请避免Sleep()。这里有一个解决方案:最好在die Idle中使用timeout或计时器来调用StopIdle。尽可能避免睡眠()。这里有一个解决方案: