我正在使用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。
问题:
基本上,我想要一个无阻塞的睡眠调用,无限期地等待而不会阻塞。
答案 0 :(得分:2)
使用Task.Delay感觉有点奇怪(特别是因为取消,这是预期的,导致CancellationException
)。我更喜欢将SemaphoreSlim
用于此类任务。
private readonly SemaphoreSlim blockUntilFinishedOrCancel = new SemaphoreSlim(0);
//Wait
await this.blockUntilFinishedOrCancel.WaitAsync():
//No More Waiting
this.blockUntilFinishedOrCancel.Release(1);
答案 1 :(得分:1)
这是替代问题的替代方法。
您需要阻止访问host.UnregisterObserversAsync()
,直到某些事件发生为止?
您可以使用Monitor来模拟producer / consumer方案等内容。
你的方法也应该做这个工作,但它看起来有点hacky ......另一方面,生产者/消费者可能对一些简单的东西有点过分。玩代码,看看哪种方式适合你。
答案 2 :(得分:0)
感谢您的所有答案和评论,通过在互联网上查看以下有关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方法。这样我就不需要不确定地睡眠/阻塞线程了。