【问题标题】:Threaded Code Is Causing the UI To Hang线程代码导致 UI 挂起
【发布时间】:2012-12-18 20:33:00
【问题描述】:

我编写了一个简单的类来生成数组,因为我需要一些硬编码的随机数组来进行自己的调试,但是尽管在单独的工作线程中调用了及时操作,但我的 UI 仍然挂起!这是代码...

    private static Random randGenerator = new Random();

    private void generateButton_Click(object sender, EventArgs e)
    {
        string dataType = "System.";
        if (typeComboBox.Text != "Byte")
            dataType += signedCheckBox.Checked ? "" : "U";
        else if (typeComboBox.Text == "Byte")
            dataType += signedCheckBox.Checked ? "S" : "";
        dataType += typeComboBox.Text;

        generateButton.Enabled = false;

        new Thread(() =>
            {
                Process(Type.GetType(dataType), (int)sizeNumericUpDown.Value, hexCheckBox.Checked);
            }).Start();
    }

    private void Process(Type type, int size, bool hex)
    {
        StringBuilder sBuilder = new StringBuilder();
        sBuilder.Append(string.Format(@"{0}[] values = new {0}[{1}] {{", type.Name, size));

        for (int i = 0; i < size; i++)
        {
            int random = randGenerator.Next(0, GetIntegralMaxValue(type));
            sBuilder.Append((hex ? "0x" + random.ToString("x2") : random.ToString()) + (i < size - 1 ? ", " : " };"));
        }

        outputTextBox.BeginInvoke((MethodInvoker)delegate
        {
            outputTextBox.Text = sBuilder.ToString();
        });
    }

    private int GetIntegralMaxValue(Type type)
    {
        var field = type.GetField("MaxValue").GetValue(null);
        return Convert.ToInt32(field);
    }

我认为问题可能在于尝试访问在主线程上创建的对象,因此我将它们传递给了方法。我还尝试在类中声明我的 randGenerator 对象,但仍然没有运气。有人能找出问题所在吗?

【问题讨论】:

  • 它是否无限期挂起?是否还有其他东西在后台运行并试图访问 UI 线程?
  • 只有在操作完成之前才可以。这是我班上唯一的代码。
  • 我们在谈论多少数据?如果它很大,则可能需要很长时间才能更新。不过,一个想法是,您可以在调用之前调用sBuilder.ToString():`var s = sBuilder.ToString(); ... outputTextBox.Text = s;
  • 在我的计算机上,挂起从 50,000 次迭代开始,而这仅持续半秒。要生成的迭代次数和随机数越多,操作所需的时间显然就越长。我试过你的建议,但没有运气。我不明白为什么 UI 会挂起,因为 GUI 线程是完全免费的。
  • 与问题无关,但为什么需要预先计算随机值?如果您总是想要相同的随机数,为什么不简单地使用带有特定(硬编码)种子的 new Random

标签: c# multithreading user-interface


【解决方案1】:

TextBox 不是为保存大量数据而设计的——当数据量增加时它会变得非常慢。我会说填充 StringBuilder 需要大约 5% 的时间,而将此数据分配给 TextBox(在 UI 线程中执行)需要剩余 95% 的时间。您可以轻松检查这一点。只需在调试模式下运行此代码,然后在挂起期间单击“暂停”按钮。它应该在“outputTextBox.Text = sBuilder.ToString();”上中断线。

【讨论】:

    猜你喜欢
    • 2012-11-08
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多