当我在单独的线程上向列表框添加随机数时,UI会冻结

本文关键字:随机数 添加 UI 冻结 列表 单独 线程 | 更新日期: 2023-09-27 18:11:17

当我使用新线程加载windows窗体时,我每秒向列表框添加一个随机数,当它达到10个数字时,我生成一个新的10个随机数集。然而,目前,我有一个问题与UI线程。随机数被添加到列表框中,但我无法控制表单。当我尝试与表单交互时,UI冻结了。我是否错误地使用了MethodInvoker ?如有任何建议,不胜感激。

public Form1()
    {
        InitializeComponent();
        Thread ranThread = new Thread(new ThreadStart(RandomList));
        ranThread.IsBackground = true;
        ranThread.Start();         
    }
public void RandomList()
    {
        stack = new Stack<int>(); 
        while (loop)
        {
            if (lbxStackRndNum.InvokeRequired)
            {
                lbxStackRndNum.Invoke(new MethodInvoker(delegate
                    {
                        Random rnd = new Random();
                        if (lbxStackRndNum.Items.Count == 10)
                        {
                            stack.Clear();
                            lbxStackRndNum.Items.Clear();
                        }
                        int rndVal = rnd.Next(1, 10000);
                        stack.Push(rndVal);
                        lbxStackRndNum.Items.Insert(0, rndVal);
                        Thread.Sleep(1000);
                    }));
            }
        }
    }

当我在单独的线程上向列表框添加随机数时,UI会冻结

你在被调用的委托中调用Thread.Sleep(1000),这意味着它将使UI线程休眠而不是ranThread

public void RandomList()
{
    stack = new Stack<int>(); 
    while (loop)
    {
        if (lbxStackRndNum.InvokeRequired)
        {
            lbxStackRndNum.Invoke(new MethodInvoker(delegate
                {
                    Random rnd = new Random();
                    if (lbxStackRndNum.Items.Count == 10)
                    {
                        stack.Clear();
                        lbxStackRndNum.Items.Clear();
                    }
                    int rndVal = rnd.Next(1, 10000);
                    stack.Push(rndVal);
                    lbxStackRndNum.Items.Insert(0, rndVal);
                }));
              Thread.Sleep(1000);
        }
    }
}

由于实际工作是通过Invoke()和委托在主UI线程中完成的,并且所有线程真正做的是通过Sleep()充当一秒钟计时器…为什么不从工具箱中添加一个常规的Timer()到表单中,将Interval设置为1000,然后将代码放在Tick()事件中呢?