繁体   English   中英

WinForms interthread修改

[英]WinForms interthread modification

每当我想从另一个线程修改winform时,我需要使用

->Invoke(delegate, params)

以便修改发生在winform自己的线程中。

对于需要修改gui的每个函数,我需要另一个委托函数。

是否有一些方案允许我限制所需的委托功能的数量? 我有一个控制器类,可以在一个地方处理整个gui,我考虑过重用代表但是闻起来很糟糕。

我认为我的问题可以适用于winform可以运行的所有语言

如果您使用的是C#3,则可以使用lambda,而在C#2中,则使用匿名委托。 当不需要重用行为时,这些简化了语法。 我经常做的一件事是在表单代码中进行同步,而不是在控制器中进行。 控制器不应该受到这种技术更具体的“管道”问题的困扰,而不是控制器逻辑。

public void ResetFields()
{
    // use "delegate" instead of "() =>" if .Net version < 3.5
    InvokeOnFormThread(() => 
    {
        firstInput.Text = Defaults.FirstInput;
        secondInput.Text = Defaults.SecondInput;
        thirdChoice.SelectedIndex = Defaults.ThirdChoice;
    });
}

// change Action to MethodInvoker for .Net versions less than 3.5
private void InvokeOnFormThread(Action behavior) 
{
    if (IsHandleCreated && InvokeRequired)
    {
        Invoke(behavior);
    }
    else
    {
        behavior();
    }
}

作为一种做法,使表单中的所有公共方法调用“InvokeOnFormThread”。 或者,您可以使用AOP拦截表单上的公共方法调用并调用“InvokeOnFormThread”,但上面已经运行得很好(如果您保持一致并记住总是在窗体或UserControls上的公共方法上执行)。

看看使用现有的System.Action<T>System.Func<T,T>委托:

control.Invoke(
    new Action<int, string>(
        (i, s) => MessageBox.Show(String.Format(s, i))), 1, "{0}");
int iret = (int) control.Invoke(new Func<int, int>(i1 => i1 + 1));

Michael Meadows的答案是如何集中更新GUI表单逻辑的一个很好的例子。

关于调用众多代表来同步前端的性能(我们很容易被痴迷),不久之前,我编写的软件在GUI同步方面优于同等的C ++(本机)Windows应用程序! 这完全归功于BeginInvokeThreadPool类。

使用Action<>Func<>委托和ThreadPool类也是有益的,并考虑一般的Invoke模式(由上面的Michael公开):

public void TheGuiInvokeMethod(Control source, string text)
{
   if (InvokeRequired)
      Invoke(new Action<Control, string>(TheGuiInvokeMethod, source, text);
   else
   {
       // it is safe to update the GUI using the control
      control.Text = text;
   }
}

其中TheGuiInvokeMethod确实位于表单或其他控件中。

我记得关闭检查并手动验证我使用的每个电话都是安全的。

由于我保证了某些线程的位置(信号量),或者因为它们调用了可以在其他进程上使用的底层API函数,因此可以将其中令人惊讶的数量称为交叉线程。

我最终仍然有很多调用,通常是在上下文对象上,所以我可以使用MethodInvoker。

我还在Control.Invoke中遇到了一个令人讨厌的错误,驱使我写一个自定义调用程序库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM