繁体   English   中英

Task.Delay(Timeout.Infinite)是一个非阻塞调用,可以用来无限期地无阻塞地进行睡眠吗?

[英]Is Task.Delay(Timeout.Infinite) a non-blocking call and can be used to sleep indefinitely without blocking?

我正在使用Cosmos DB Change Feed库来处理来自Change Feed的文档。

var docObserverFactory = DocumentFeedObserverFactory.Create(myCollectionInfo);
await host.RegisterObserverFactoryAsync(docObserverFactory);
Console.WriteLine("Awaiting indefinitely...press Cancel to exit");

// I set the CancellationToken to true on Console.CancelKeyPress Event
await Task.Delay(Timeout.Infinite, cancellationToken);
await host.UnregisterObserversAsync();

在上面的代码中,在注册观察者工厂之后,我需要保持这个线程一段不确定的时间。 因此我使用具有无限超时值的Task.Delay。

问题:

  1. 我想知道以这种方式使用Task.Delay()是否正确。
  2. 我担心Task.Delay()会在无限超时的情况下在内部阻塞一个线程来监视取消令牌。

基本上,我想要一个无阻塞的睡眠调用,无限期地等待而不会阻塞。

使用Task.Delay感觉有点奇怪(特别是因为取消,这是预期的,会导致CancellationException )。 我更喜欢使用SemaphoreSlim来完成这样的任务。

    private readonly SemaphoreSlim blockUntilFinishedOrCancel = new SemaphoreSlim(0);

    //Wait
    await this.blockUntilFinishedOrCancel.WaitAsync():

    //No More Waiting
    this.blockUntilFinishedOrCancel.Release(1);

这是另一种选择,而不是问题的答案。

您需要阻止对host.UnregisterObserversAsync()的访问,直到某些事件发生为止?

您可以使用Monitor来模拟生产者/消费者场景。

你的方法也应该做的工作,但它看起来有点hacky ...另一方面,生产者/消费者可能是一个简单的过度杀手。 玩代码,看看你觉得什么。

感谢您的所有答案和评论,通过在互联网上查看以下有关Change Feed使用的代码,我意识到这是错误的。 特别误解了“Console.ReadLine”阻塞线程,我需要做同样的事情。 但是没有必要阻止此线程取消注册它。 它可以由任何其他线程完成。

using (DocumentClient destClient = new DocumentClient(destCollInfo.Uri, destCollInfo.MasterKey))
{
    DocumentFeedObserverFactory docObserverFactory = new DocumentFeedObserverFactory(destClient, destCollInfo);

    ChangeFeedEventHost host = new ChangeFeedEventHost(hostName, documentCollectionLocation, leaseCollectionLocation, feedOptions, feedHostOptions);
    await host.RegisterObserverFactoryAsync(docObserverFactory);

    // This is where I thought I need to block this thread indeterminately.
    Console.WriteLine("Running... Press enter to stop.");
    Console.ReadLine();

    await host.UnregisterObserversAsync();
}

作为替代方案,我可以将ChangeFeedEventHost作为我的类的一部分,并公开一个方法来取消注册它。 在CancelKeyPress事件中,我可以调用该unregsiter方法。 这样我就不需要不确定地睡眠/阻塞线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM