2011-07-07 34 views
1

我有一个阻塞库调用,一个imap Idle,它将在一个长时间运行的服务中等待电子邮件,我很偏执,并且不信任这个库永远不会错过一封电子邮件。通过并发呼叫StopIdle可以取消空闲呼叫。如果它认为它仍然空转,我实施以下方法来每分钟拨打StopIdle。用TPL创建阻塞方法调用的超时时间

有没有更好的方法来做到以下几点?这种方法的工作原理,但似乎我最终会占用一堆线程池线程,只是睡觉。

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

更好地使用超时插座空闲或定时器来调用您的StopIdle。如果可以,避免睡眠()。 –

+0

这里有一个解决方案:http://stackoverflow.com/questions/11831844/unobservedtaskexception-being-throw-but-it-is-handled-by-a-taskscheduler-unobser?lq=1 – 2012-11-22 17:38:42

回答

1

使用亨克的建议,我重写它使用定时器是:

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

client.Idle(); 

stopIdleTimeoutTimer.Dispose(); 

自库,我没有访问代码,我不能改变空闲的行为方法