有2个WaitCallback的ThreadPool有时会卡住

时间:2014-08-03 21:00:27

标签: c# threadpool queueuserworkitem

我尝试使用ThreadPool.QueueUserWorkItem,但似乎如果我运行其中2个,意味着:

ThreadPool.QueueUserWorkItem(new WaitCallback(x=>function A); 
ThreadPool.QueueUserWorkItem(new WaitCallback(x=>function B);

它有时会卡住不到一秒钟。 有什么想法吗?

其中一个电话是游戏倒数计时器:

ThreadPool.QueueUserWorkItem(new WaitCallback(x=>initClock(0,0)));

private void initClock(int sec , int hunS)
{
    int half = gameClock / 2;
    seconds = sec;
    while (true)
    {   
        while (clockLock == false && seconds < gameClock)
        {
            hunSec = hunS;
            while (clockLock == false && hunSec < 100)
            {
                Thread.Sleep(10);
                updateClock(seconds, hunSec);
                hunSec++;
            }
            seconds++;
            if (half == seconds)
            {
                panel5.BackColor = Color.Red;
            }
        } 
    }
}

private void updateClock(int sec, int secRem)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action<int, int>(updateClock), sec, secRem);
    }
    else
    {                
        clock_Label.Text = sec.ToString() + ':' + secRem.ToString();
    }
}

2 个答案:

答案 0 :(得分:1)

你是否正在开始许多这些任务,每个任务都会阻塞很长时间?根据给出的信息可能就是这种情况。

这意味着很多线程一次可以处于活动状态。当您使用高于最小限制的线程池时,另一个线程将受到限制(我相信)500ms。这可能是你看到的延迟。

如何解决这个问题?

  1. 开始减少线程。使用异步IO和异步等待。那些不使用任何线程。使用await可以很容易地做到这一点。
  2. 增加线程池最小限制。 SetMinThreads

答案 1 :(得分:0)

那里有些可疑的东西。 initClock什么时候结束?退出应用程序时看起来永远不会或更像它。

因此,如果您使用入口点initClock启动许多线程池线程,那就是线程池容量用完的原因。在这种情况下,增加min线程的数量并不重要,它仍然会像这样。

我不知道它背后的逻辑,但我认为你希望它在剩余的秒数为0时结束。所以,你纠正这个可能行为是固定的。

最后一件事;此语句更新UI:

        if (half == seconds)
        {
            panel5.BackColor = Color.Red;
        }

您应该将其执行权分配给UI线程(通过Invoke,就像您对updateClock所做的那样)。我知道它可能有用,但这并不能使它正确。

  

它有时会卡住不到一秒钟。有任何想法吗?   您必须引用在UI中观察到的内容,标签clock_Label未按预期更新。

好吧,我会降低该标签的刷新率。当你更新它时,你每隔10ms就会这样做。这有必要吗?由于您在此标签中显示秒数,因此您可以将间隔增加到500毫秒。看看它在响应性方面有何不同。