簡體   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