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

查看:2460
本文介绍了奇怪的行为当我不使用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 with 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天全站免登陆