I have a blocking library call, an imap 开发者_运维百科Idle that will be in a long running service waiting for email, I'm paranoid and don't trust the library to never miss an email. The Idle call can be cancelled by a concurrent call to StopIdle. I implemented the following way to every minute call StopIdle if it thinks its still idling.
Is there a better way to do the following? This methods works but it seems like I will end up taking up a bunch of thread pool threads just sleeping.
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();
}
Using Henk's suggestion I rewrote it using a timer to be:
Timer stopIdleTimeoutTimer = new Timer(
_ => client.StopIdle(),
null,
TimeSpan.FromMinutes(1),
TimeSpan.FromMilliseconds(-1));
client.Idle();
stopIdleTimeoutTimer.Dispose();
Since its a library that I don't have access to the code I can't alter the behavior of the Idle method
精彩评论