【发布时间】: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