2

我正在尝试使用 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();
    }
}
4

2 回答 2

1

你是否开始了许多这样的任务,每个任务都阻塞了很长时间?根据提供的信息,情况可能如此。

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

如何解决这个问题?

  1. 启动更少的线程。使用异步 IO 和异步等待。那些不使用任何线程。await这样做很容易。
  2. 增加线程池的最小限制。SetMinThreads.
于 2014-08-03T21:21:51.487 回答
0

里面有腥味。什么时候initClock结束?当您退出应用程序时,看起来从来没有,或者更像它。

因此,如果您使用入口点启动许多线程池线程,initClock那么这就是您用完线程池容量的原因。在这种情况下,无论您增加多少最小线程,它仍然会表现得像这样。

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

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

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

您应该真正将其执行分派给 UI 线程(通过Invoke,就像您为 所做的那样updateClock)。我知道它可能有效,但这并不意味着它是正确的。

它有时会卡住不到一秒钟。有任何想法吗?您必须指的是您在 UI 中观察到的内容,该标签clock_Label不会像您预期的那样快速更新。

好吧,我会降低该标签的刷新率。当您更新它时,您每 10 毫秒更新一次。那有必要吗?由于您在此标签中显示秒数,您不妨将间隔增加到 500 毫秒。看看它在响应方面有什么不同。

于 2014-08-03T21:44:59.343 回答