【问题标题】:While (true) loop in a Task silently exits任务中的 While (true) 循环静默退出
【发布时间】: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


【解决方案1】:

我不相信Thread.Sleep 在无限循环和内部任务中。您至少应该使用适当的计时器。

为了做这种事情,我会使用微软的响应式框架(称为“Rx”)。

代码如下:

var subscription =
    Observable
        .Interval(TimeSpan.FromSeconds(1.0))
        .Subscribe(n =>
        {
            ProcessMessages();
        });

基本上它会设置一个计时器来处理您的消息。

当您希望它停止时,只需执行subscription.Dispose()

您可以 NuGet "Rx-Main" 来获取这些位。

【讨论】:

  • 因为您强制创建线程,而不是让计时器并行运行而不会导致任何问题
  • @user1306322 - Thread.Sleep 不是计时器。它更像是一台时光机。
  • @Enigmativity:我不知道,在未知数量的后台线程中启动Timers 总是让我偏执,因为Timer 会占用一些非常真实的操作系统资源。
  • @code4life - Rx 非常有效地管理计时器。我相信您最终每个调度程序只有一个。
  • @Enigmativity:如果 bg 线程必须共享资源,则不确定增值是什么——在这种情况下,每个调度程序只有一个计时器的瓶颈。这意味着一些线程只是在它们可以被计时器服务之前就坐在那里,不是吗?此外,定时器到线程的通信意味着线程跳转,因为每个线程都存在于自己的线程中,这可能不是预期的结果。我不知道,仍然不相信计时器是最好的方法。许多小而关键的问题通过使用计时器被扫到了地毯下。感觉就像用大锤敲小钉子一样。恕我直言,有效,但有时矫枉过正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
相关资源
最近更新 更多