简体   繁体   English

为什么 Task.WhenAny() 没有按预期工作

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

I'm trying to implement a timeout pattern for an awaitable task as described here: https://stackoverflow.com/a/11191070我正在尝试为可等待任务实现超时模式,如下所述: https://stackoverflow.com/a/11191070

However, I am getting unexpected results.但是,我得到了意想不到的结果。 I've written a small console app to demonstrate (bottom of this post).我编写了一个小型控制台应用程序来演示(这篇文章的底部)。 These are the scenarios and results I get:这些是我得到的场景和结果:

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

Can anyone shed any light as to why this is not functioning as expected.任何人都可以解释为什么它没有按预期运行。 TIA!蒂亚!

   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);
        }
    }

Because your dummy methods are implemented incorrectly.因为您的虚拟方法实施不正确。 Change Thread.Sleep to await Task.Delay :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);
 }

What is happening right now in your code:您的代码中现在发生了什么:

  1. var task = ActualTask(_cancelWorkTokenSource.Token) blocks current thread for 10000 milliseconds and returns completed Task var task = ActualTask(_cancelWorkTokenSource.Token)阻塞当前线程 10000 毫秒并返回完成的任务
  2. After that var delayTask = DelayTask(_cancelWorkTokenSource.Token);之后var delayTask = DelayTask(_cancelWorkTokenSource.Token); blocks current thread for 100 milliseconds and returns completed task阻塞当前线程 100 毫秒并返回已完成的任务
  3. await Task.WhenAny(task, delayTask) selects first of them cause both are completed await Task.WhenAny(task, delayTask)选择其中的第一个,因为两者都已完成

Add to your code Console.WriteLine(task.IsCompleted);添加到您的代码Console.WriteLine(task.IsCompleted); and Console.WriteLine(delayTask.IsCompleted);Console.WriteLine(delayTask.IsCompleted); after corresponding variables initialization to check it.在相应的变量初始化后检查它。

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

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