【问题标题】:Thread.Sleep and Task.Delay randomly hanging and never endsThread.Sleep 和 Task.Delay 随机挂起且永不结束
【发布时间】:2018-09-07 08:44:05
【问题描述】:

不是重复的。下面的代码也会挂起并导致控制台“随机”等待输入 - 某个地方存在更大的潜在问题。

int i = 0;
while (true)
{
    Console.WriteLine(++i);
    System.Threading.Thread.Sleep(3000);
}

所以我有一个最奇怪的错误,网上似乎从来没有这个错误。我最近将我的任务调度程序移到了另一台服务器(Windows server 2016 标准),并且由于移动,应用程序似乎随机挂在 Task.Delay 行上并且永远不会执行超过它。

例如,它会简单地说“检查在 09:31 完成下一次运行”,然后不再执行。

有趣的是,在控制台窗口中按 enter 似乎会触发它执行,但是每次它都会挂在睡眠状态,直到应用程序关闭并重新打开。

它可以持续很多天都没有遇到这个问题,然后它似乎会随机出现。

我尝试过使用 Thread.Sleep 而不是 Task.Delay 并且都遇到了同样的问题。我还添加了一个检查,以查看 Directory.Exists 命令是否可能导致它挂起,因此将目录存储在内存中。

我不知道是什么原因造成的——我以前从未经历过这样的事情。有什么想法吗?

代码如下 - 但是由于错误的怪异性质,无法复制 id 想象

TLDR: Windows Server 2016 控制台应用程序在 Task.Delay(和 Thread.Sleep)上挂起,直到按键按下控制台窗口

        // This is the main execution loop
            while (true)
        {
            Task run = checkDirectoriesForAppsToRun();
            run.Wait();
        }

       static async Task checkDirectoriesForAppsToRun()
    {
        Console.WriteLine("Starting apps...");
        foreach (string subFolder in listOfSubfolders)
        {
            if (directoryExists.ContainsKey(currentDirectory + @"\" + subFolder) || System.IO.Directory.Exists(currentDirectory + @"\" + subFolder)) // Only if the sub directory exists!
            {
                if (directoryExists.ContainsKey(currentDirectory + @"\" + subFolder) == false)
                    directoryExists.Add(currentDirectory + @"\" + subFolder, true);
                foreach (string directory in System.IO.Directory.GetDirectories(currentDirectory + @"\" + subFolder))
                {
                    CheckDirectoryForApp(directory); // Load the apps xml file, and check if we need to run it.
                }
            }
            else
            {
                Console.WriteLine(subFolder + " Doesn't exist in the root directory - Please check");
            }
        }
        Console.WriteLine("Check completed next run at " + DateTime.Now.Add(timeToPause).ToShortTimeString());
        await Task.Delay(timeToPause);
    }

【问题讨论】:

  • 旁注 为什么不使用System.Threading.Timer 而不是创建自己的循环版本?
  • Task.Delay() 不会阻止。 Thread.Sleep() 就是这样做的。你不应该使用.Wait(),那阻塞。将您的代码更改为 await 该任务。将延迟放在工作函数之外。循环应该看起来像while(someRealCondition){ await checkDirectoriesForAppsToRun(); await Task.Delay(..);}
  • @Jeax 没有澄清任何事情。使用 Thread.Sleep() 是错误的。 Task.Delay 不会阻塞,但 this 代码很容易导致死锁。在await 执行后返回到原来的同步上下文。在桌面应用程序中,这就是 UI 线程。被.Wait() 阻止。 ==> 死锁
  • @Jeax 也发布了循环的代码。并考虑使用计时器。
  • @Jeax pressing enter into the console window 这可能意味着您在某处有一个 Console.ReadLine 或 Console.ReadKey。

标签: c# task console-application thread-sleep windows-server-2016


【解决方案1】:

为什么不使用System.Threading.Timer 而不是创建自己的循环版本?这就是他们被创造的目的。关于为什么发布的代码会/可能会死锁的问题,请参阅已经非常出色的 cmets,如果您将同步调用与 async/await 混合使用,这很容易做到,并且也没有必要使用 async/await,因为您只使用它为Task.Delay

private static System.Threading.Timer _timer;

static void Main(string[] args)
{
  // start the timer
  _timer = new System.Threading.Timer(checkDirectoriesForAppsToRun, null, 0, timeToPause);
}

static void StopTimer()
{
  // call this method when you want to stop the timer
  _timer?.Dispose();
}


static void checkDirectoriesForAppsToRun(object state)
{
  Console.WriteLine("Starting apps...");
  /* exising code not considered in this answer... */
  Console.WriteLine("Check completed next run at " + DateTime.Now.Add(timeToPause).ToShortTimeString());

  // await Task.Delay(timeToPause); // removed
}

【讨论】:

  • 嗨,伊戈尔。刚刚使用它,它显示了完全相同的问题。但是我感谢您的帮助-但似乎某处发生了一些非常错误的事情,这似乎甚至可以延续到.NETs自己的Timer类中。对于它的价值,它在失败之前成功运行了 5 次。这与我尝试过的所有其他方法一致,因为它将在确定的时间内工作,然后“突然”停止。可以是几分钟,也可以是几天。
【解决方案2】:

因此,这似乎是 RDP 连接在运行时冻结 .NET 应用程序的问题。

在 Windows Server 2008 上不是问题 - 在更高版本的 Windows Server 上是一个问题。请参阅下面的链接。目前无法解决 - 摆脱 RDP 以支持 VNC 以回避问题

https://social.msdn.microsoft.com/Forums/vstudio/en-US/f1d6d2e3-417f-4bc4-be83-1e659852d6cb/application-hang-when-using-remote-desktop?forum=vcgeneral

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-23
    • 2021-08-05
    • 2021-12-22
    • 2019-11-12
    • 2018-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多