而任务中的(true)循环以静默方式退出

时间:2015-10-20 00:06:46

标签: c# task-parallel-library infinite-loop

我制作了一个聊天机器人应用程序,它通过所有收到的消息并以指定的间隔(约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子句中,它们也不会被记录?什么可以使循环突然结束?如何让我的应用程序更可靠?

1 个答案:

答案 0 :(得分:2)

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

要做这种事情,我会使用Microsoft的Reactive Framework(称为“Rx”)。

以下是代码:

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

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

如果您希望停止,请执行subscription.Dispose()

您可以通过NuGet“Rx-Main”获取位。