簡體   English   中英

為什么 Task.WhenAny() 沒有按預期工作

[英]Why does Task.WhenAny() not working as expected

我正在嘗試為可等待任務實現超時模式,如下所述: https://stackoverflow.com/a/11191070

但是,我得到了意想不到的結果。 我編寫了一個小型控制台應用程序來演示(這篇文章的底部)。 這些是我得到的場景和結果:

Scenario 1
DelayTask  Thread.Sleep(10000);
ActualTask Thread.Sleep(100);
Invoked with await Task.WhenAny(...
Result: THEN clause invoked  CORRECT

Scenario 2
DelayTask  Thread.Sleep(100);
ActualTask Thread.Sleep(10000);
Invoked with await Task.WhenAny(...
Result: THEN clause invoked  INCORRECT

Scenario 3
DelayTask  Thread.Sleep(10000);
ActualTask Thread.Sleep(100);
Invoked WITHOUT await: Task.WhenAny(...
Result: ELSE clause invoked  INCORRECT

Scenario 4
DelayTask  Thread.Sleep(100);
ActualTask Thread.Sleep(10000);
Invoked WITHOUT await: Task.WhenAny(...
Result: ELSE clause invoked  CORRECT

任何人都可以解釋為什么它沒有按預期運行。 蒂亞!

   class Program
    {

        static void Main(string[] args)
        {
            Run();
        }

        private static async void   Run()
        {
            var _cancelWorkTokenSource = new CancellationTokenSource();
            var task = ActualTask(_cancelWorkTokenSource.Token);
            var delayTask = DelayTask(_cancelWorkTokenSource.Token);

            if (await Task.WhenAny(task, delayTask) == task)
            {
                Console.WriteLine("Task Succeeded in time."); 
            }
            else
            {
                Console.WriteLine("Task exceeded time limit");
            };

            Console.ReadLine();
        }

        private static async Task DelayTask(CancellationToken cancelToken)
        {
            Thread.Sleep(10000);
        }

        private static async Task ActualTask(CancellationToken cancelToken)
        {
            Thread.Sleep(100);
        }
    }

因為您的虛擬方法實施不正確。 Thread.Sleep更改為await Task.Delay

private static async Task DelayTask(CancellationToken cancelToken)
{
    await Task.Delay(10000);
}

 private static async Task ActualTask(CancellationToken cancelToken)
 {
    await Task.Delay(100);
 }

您的代碼中現在發生了什么:

  1. var task = ActualTask(_cancelWorkTokenSource.Token)阻塞當前線程 10000 毫秒並返回完成的任務
  2. 之后var delayTask = DelayTask(_cancelWorkTokenSource.Token); 阻塞當前線程 100 毫秒並返回已完成的任務
  3. await Task.WhenAny(task, delayTask)選擇其中的第一個,因為兩者都已完成

添加到您的代碼Console.WriteLine(task.IsCompleted); Console.WriteLine(delayTask.IsCompleted); 在相應的變量初始化后檢查它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM