Thread.Sleep 和 Task.Delay 随机挂起,永不结束
Thread.Sleep and Task.Delay randomly hanging and never ends
不是重复的。下面的代码也挂起并导致控制台等待输入 'randomly' - 某处更大的潜在问题。
int i = 0;
while (true)
{
Console.WriteLine(++i);
System.Threading.Thread.Sleep(3000);
}
所以我遇到了最奇怪的错误,网上似乎没有任何错误。我最近将我的任务调度程序移到了另一台服务器(Windows 服务器 2016 标准)并且由于移动应用程序似乎随机挂在 Task.Delay 行并且永远不会执行过去。
它会简单地说'Check completed next run at 09:31',然后不再执行。
有趣的是,按 enter 进入控制台 window 似乎会触发它执行,但是每次它都挂在睡眠状态,直到应用程序关闭并重新打开。
可能很多天都没有遇到这个问题,然后它似乎是随机出现的。
我试过使用 Thread.Sleep 而不是 Task.Delay,但都遇到了同样的问题。我还添加了一个检查以查看 Directory.Exists 命令是否可能导致它挂起,因此将目录存储在内存中。
我不知道是什么原因造成的 - 我以前从未经历过类似的事情。有什么想法吗?
代码在下面 - 但是由于错误的奇怪性质,将无法复制 id imagine
TLDR:
Windows 服务器 2016 控制台应用程序在 Task.Delay(和 Thread.Sleep)上挂起,直到在控制台 window
上按下按键
// 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
而不是创建自己的循环版本?这就是它们的创建目的。请参阅关于为什么发布的代码 would/could 会死锁的问题的已经很好的评论,如果您将同步调用与 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
}
所以这似乎是 RDP 连接在运行时冻结 .NET 应用程序的问题。
在 Windows 服务器 2008 上不是问题 - 在后来的 windows 服务器版本上是问题。请参阅下面的 link。目前无法解决 - 摆脱了 RDP,转而使用 VNC 来回避问题
不是重复的。下面的代码也挂起并导致控制台等待输入 'randomly' - 某处更大的潜在问题。
int i = 0;
while (true)
{
Console.WriteLine(++i);
System.Threading.Thread.Sleep(3000);
}
所以我遇到了最奇怪的错误,网上似乎没有任何错误。我最近将我的任务调度程序移到了另一台服务器(Windows 服务器 2016 标准)并且由于移动应用程序似乎随机挂在 Task.Delay 行并且永远不会执行过去。
它会简单地说'Check completed next run at 09:31',然后不再执行。
有趣的是,按 enter 进入控制台 window 似乎会触发它执行,但是每次它都挂在睡眠状态,直到应用程序关闭并重新打开。
可能很多天都没有遇到这个问题,然后它似乎是随机出现的。
我试过使用 Thread.Sleep 而不是 Task.Delay,但都遇到了同样的问题。我还添加了一个检查以查看 Directory.Exists 命令是否可能导致它挂起,因此将目录存储在内存中。
我不知道是什么原因造成的 - 我以前从未经历过类似的事情。有什么想法吗?
代码在下面 - 但是由于错误的奇怪性质,将无法复制 id imagine
TLDR: Windows 服务器 2016 控制台应用程序在 Task.Delay(和 Thread.Sleep)上挂起,直到在控制台 window
上按下按键 // 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
而不是创建自己的循环版本?这就是它们的创建目的。请参阅关于为什么发布的代码 would/could 会死锁的问题的已经很好的评论,如果您将同步调用与 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
}
所以这似乎是 RDP 连接在运行时冻结 .NET 应用程序的问题。
在 Windows 服务器 2008 上不是问题 - 在后来的 windows 服务器版本上是问题。请参阅下面的 link。目前无法解决 - 摆脱了 RDP,转而使用 VNC 来回避问题