当我不使用 TaskCreationOptions.LongRunning 时的奇怪行为 [英] Strange Behavior When I Don't Use TaskCreationOptions.LongRunning

查看:14
本文介绍了当我不使用 TaskCreationOptions.LongRunning 时的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个引擎,它有任意数量的轮询器,每个轮询器每隔几秒钟就进行一次轮询".我希望轮询器在不同的线程中运行,但单个轮询器中的每个轮询"应该是顺序的,以便一个在下一个之后发生.一切都在使用此代码启动轮询过程:

I have an engine that has an arbitrary number of pollers which each do their "poll" every few seconds. I want the pollers to run in different threads, but each "poll" within a single poller should be sequential so that one happens after the next. Everything is working using this code to start the polling process:

    public void StartPolling()
    {
        Stopwatch watch = new Stopwatch();
        while (Engine.IsRunning)
        {
            Task task = Task.Factory.StartNew(() =>{
                watch.Restart();
                Poll();
                watch.Stop();
            },TaskCreationOptions.LongRunning);
            task.Wait();
            if(Frequency > watch.Elapsed) Thread.Sleep(Frequency - watch.Elapsed);
        }
    }

然而,我花了一段时间才发现 TaskCreationOptions.LongRunning 选项,它解决了一个我仍然不明白的奇怪问题.如果没有这个选项,如果我运行一个测试来创建 1-3 个这些轮询器,一切正常.如果我创建了 4+,那么我就会遇到奇怪的行为.三个轮询器可以工作,一个只执行一次轮询,其余的则根本不进行轮询.我的任务长时间运行是完全有道理的.毕竟,它们运行了我整个程序的长度.但是我不明白为什么没有设置这个选项我会得到一些不好的行为.任何帮助将不胜感激.

It took me awhile, however, to discover the TaskCreationOptions.LongRunning option which solved a strange problem I was having that I still don't understand. Without that option, if I run a test that creates 1-3 of these pollers, everything worked fine. If I created 4+ then I ran into strange behavior. Three of the pollers would work, one would just perform one poll, and any remaining would not poll at all. It makes total sense that my tasks are long running. They are after all running the entire length of my program. But I don't understand why I would get some bad behavior without this option set. Any help would be appreciated.

推荐答案

当你不使用 LongRunning 标志时,任务被安排在线程池线程上,而不是它自己的(专用)线程.这可能是您行为改变的原因 - 当您在没有 LongRunning 标志的情况下运行时,您可能会由于进程中的其他线程而导致线程池饥饿.

When you don't use the LongRunning flag, the task is scheduled on a threadpool thread, not its own (dedicated) thread. This is likely the cause of your behavioral change - when you're running without the LongRunning flag in place, you're probably getting threadpool starvation due to other threads in your process.

话虽如此,你上面的代码并没有多大意义.您正在启动一个专用线程(通过 Task....StartNew 和 LongRunning)来启动一个任务,然后立即调用 task.Wait(),这会阻止当前线程.最好在当前线程中按顺序执行此操作:

That being said, your above code doesn't really make a lot of sense. You're starting a dedicated thread (via Task....StartNew with LongRunning) to start a task, then immediately calling task.Wait(), which blocks the current thread. It would be better to just do this sequentially in the current thread:

public void StartPolling()
{
    Stopwatch watch = new Stopwatch();
    while (Engine.IsRunning)
    {
        watch.Restart();
        Poll();
        watch.Stop();
        if(Frequency > watch.Elapsed) Thread.Sleep(Frequency - watch.Elapsed);
    }
}

这篇关于当我不使用 TaskCreationOptions.LongRunning 时的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆