C#阻塞线程取消

时间:2017-04-29 18:33:04

标签: c# task

我目前正在开发一种基本上等待流上数据的服务。该服务可以随时取消,但在大多数情况下,它可以运行很长一段时间(天)。我喜欢将我的异步设计从使用BackgroundWorker切换到一个循环,该循环使用Tasks检查BackgroundWorker的当前取消状态以及流上的某些数据的可用性(更好的设计){{{ 1}}不是长时间运行线程的最佳选择,因为它需要一个ThreadPool-Thread)。

我当前的循环/例程看起来基本上是这样的:

BackgroundWorker

我现在基本上想要做的是摆脱while(!cancelled) { CheckIfDataAvailable(); // This check is non-blocking Thread.Sleep(500); } 调用,但同时线程应该在相当长的时间内取消,同时还要监听流上是否有任何数据(并且此操作可能会阻止流或阻止以其他方式检查取消状态。)

我知道如何使用Thread.Sleep()取消Task,但我不知道任何方法以非常干净的方式结合取消检查和数据可用性检查(例如,不使用{{} 1}})。

1 个答案:

答案 0 :(得分:1)

使用Task.Delay,例如,如下所示:

async Task BackgroundWord(CancellationToken token)
{
    CheckIfDataAvailable();
    await Task.Delay(TimeSpan.FromSeconds(x), token);
}

如果您的CheckIfDataAvailable方法返回Task(在数据可用时完成),您可以将两者结合起来,如下所示:

await Task.WhenAny(CheckIfDataAvailable(), Task.Delay(-1, token));

Task.Delay(-1)将永远等待,因此如果取消令牌被取消,它将仅转移到已完成状态。因此Task.WhenAny将等待数据可用或要取消令牌。

相关问题