【发布时间】:2015-10-20 00:06:46
【问题描述】:
我制作了一个聊天机器人应用程序,它会检查所有收到的消息并以指定的时间间隔(约 1 秒)对其进行响应。负责的代码部分如下所示:
Task.Factory.StartNew(() => DoWork());
void DoWork()
{
try {
while (true)
{
ProcessMessages();
Thread.Sleep(sleepInterval);
}
}
catch(Exception ex) {Log(ex + "");}
}
问题是这个循环有时会退出而不显示任何消息或没有抛出和记录异常。我在某处读到Thread.Sleep() 可能是问题所在,因为系统可能认为该任务没有响应并尝试终止它,因此应将其更改为EventWaitHandle 并改为waitHandle.WaitOne(sleepInterval),但这对我没有帮助.
我在调试时运行应用程序,当我看到应用程序没有工作时,我在循环内设置了一个断点,并且 Visual Studio 不会暂停。处理任务中的计时器显示它们已经有一段时间没有更新了。 “无限”循环只是默默地死去。
这是一个 winforms 应用程序,我注意到有时它们在调试模式下运行时不会自动中断,即使抛出异常也是如此。但我只知道当异常源自控件方法之一调用的代码中的某处时才会发生这种情况。不过这是Task,所以我不知道它是否应该以同样的方式工作。
处理方法中的代码可能会抛出异常,但是为什么即使调用在 try-catch 子句中,它们也不会被记录?什么可以使循环突然结束?如何让我的应用更可靠?
【问题讨论】:
-
几乎总是这样,如果你使用
Thread.Sleep,你可能做错了什么。 -
如果它是一个 WinForms 应用程序,使用计时器并在每次滴答声时运行
ProcessMessages而不是制作Task不是更简单吗?或者更好的是,让它成为事件驱动的,并在现实中响应消息。 -
您还应该取出
catch(Exception ex),看看是否在某处弹出有意义的错误。通用捕获是一件坏事。 -
@Enigmativity:
Thread.Sleep并不总是意味着你做错了什么。有时您需要这样做以避免 CPU 负担过重。示例:监听套接字的“永远”循环。 -
@code4life - “错误”可能不是最好的词,但通常有比
Thread.Sleep更好的方法。
标签: c# task-parallel-library infinite-loop