1

我是一个狂热的开发者,而不是一个专业的开发者,因此我对为什么有些问题是这样的没有高度的技术理解。最近,我一直在研究应用程序,我一直在尝试通过使用后台工作程序来处理各种数据库调用来提高响应能力。

后台工作人员完成后,我需要更新 UI,因此我通常会执行以下操作:

    private delegate void safeSetTextDelegate(Control control, string text);
    public static void SafeSetText(this Control control, string text)
    {
        if(control.InvokeRequired)
        {
            safeSetTextDelegate _delegate = new safeSetTextDelegate(SafeSetText);
            control.Invoke(_delegate, new object[] { control, text});
        }
        else
        {
            control.Text = text;
        }
    }

现在,显然这有效。但是随着我发现我需要的扩展方法的数量开始增长(我有它们用于设置样式、动态添加子控件、向 datagridviews 添加行等),我想知道为什么没有一组标准方法可用.Net WinForms 语言/模型用于这些类型的事情,甚至为什么 InvokeRequired 检查不会在幕后自动进行并且根据需要应用委托(我的猜测是这是一个性能问题 - 为什么要检查调用在大多数情况下根本不需要线程)。我试图对此进行研究,但没有找到任何体面的答案。

如果我将其总结为一组问题:

  1. 我的方法中是否有任何固有的坏/错误(后台工作人员通过检查的扩展方法更新控件InvokeRequired
  2. 我在想为什么 .Net WinForms 中的各种方法不能自动InvokeRequired进行正确的检查(调用 InvokeRequired 有多少开销)?
  3. 同样,.Net WinForms 规范中不存在用于常见 UI 更新的线程安全方法是否有原因?
4

1 回答 1

1

waay waay 太繁琐了,说你有你想在 textBox1 中设置的文本

   textBox1.Invoke(()=>{
         textBox1.Text = "New Value";
    }

如果您真的担心在不需要时执行调用的开销(我不会)那么做

    var act = {
         textBox1.Text = "New Value";
    }
    if(textBox1.InvokeRequired)
          textBox1.invoke(act);
    else 
       act();

我这样做是为了看看有多少开销

        for (int i = 0; i < 1000; i++)
            checkBox1.Invoke(act);

这花了 0.0038 秒。

相对

     for(int i = 0; i< 1000; i++){
            checkBox1.Checked = true;
        }

这花了 0.0000050 秒

所以有一个不小的开销,但并不多。由于几乎所有的 winforms 应用程序都不需要这种开销,因此对所有人强加它似乎有点多

为什么会这样,它不是线程安全(如在竞争条件等中),它与窗口深处的 UI 管道有关

我可以说写了很多winforms 代码,是的,这很烦人,但修复很简单(现在我已经向你展示了我会做什么)

于 2022-03-01T01:07:20.963 回答