Winformsmultithreading:每次在UI线程上调用方法时都要创建一个新的委托吗?

我想调用一个操作UI线程控件的方法。 我的代码有效,我想优化。 我指的是MSDN上的这个资源 。
根据那里,我们应该这样做

public delegate void myDelegate(int anInteger, string aString); //... Label1.Invoke(new myDelegate(myMethod), new Object[] {1, "This is the string"}); 

这会在每次调用时引入一个孤立的委托对象(内存泄漏)吗?

当我像下面那样使用委托的静态实例时,然后在每次调用时使用此实例来调用:

 private static _delegateInstance = new myDelegate(myMethod); //... Label1.Invoke(_delegateInstance , new Object[] {1, "This is the string"}); 

这是线程安全吗? 我认为这会有更好的性能,因为委托实例只创建一次?

这会在每次调用时引入一个孤立的委托对象(内存泄漏)吗?

不,不行,没关系。

但是为了避免在每次使用某些现有代码时创建委托(如果你的方法需要2个字符串参数但没有返回):

 Label1.Invoke.Invoke((Action)myMethod, new object[] { 1, "This is the string" }); 

上面的两个答案给出了一些见解。 如果你想获得更深入的信息, 这里有一篇很好的文章。

这两种方法都是线程安全的,因为在调用时,线程池为每次调用分配一个线程。 存在锁定的可能性,但是如果您阅读该文章,那么可以解决这个问题。

此外,您需要记住.Net处理UI线程的方式略有不同。 如果您正在处理WPF,则必须考虑调度员。 看到这里 。

最终,我不确定你会用第二段代码获得巨大的性能提升,所以我倾向于坚持第一段。

N.

另一种“模式”(如果可以调用它)是让方法只调用自己,假设它是Form类的一部分:

 void myMethod(int anInteger, string aString) { if (InvokeRequired) { Invoke(new Action(myMethod),anInteger,aString); return; } Label1.Text = aString; } 

Action对象将保留在堆上,更改text属性,然后在下一次扫描时进行GC’d。 除非该方法保留一些外部资源,例如IE的句柄,文件等,否则我无法看到它是性能损失。

首先,C#是一种托管语言,因此没有内存泄漏。 永远。

其次,当您尝试优化时,不要将MSDN作为最终裁决。 您在那里找到的许多代码片段甚至都不符合MS自己的编码标准(即使是最基本的编码标准)甚至是常识。

三,行:private _delegateInstance = new myDelegate(myMetho); 没有创造任何静态的东西。 它创建一个变量,用于保存从新myDelegate(myMethod)返回的新实例。

最后,使用“new”关键字肯定会在每次调用中创建新的myDelegate对象,以及与您编写的第二个代码段完全不同的行为,但在某些情况下,这是必需的。

您可能想要使用您编写的第二个选项,但真正的事实是您应该花时间阅读\了解更多关于委托和C#的信息。

祝你好运,享受。

您的第一个代码段每次都会创建一个委托对象实例。 这不会导致任何泄漏,但会增加需要进行垃圾回收的对象数量。

您的第二个代码段不会每次都创建委托对象,但是不可能(假设myMethod是一个实例方法),因为静态成员不能使用实例成员。

Darin Dimitrov错了 – 他的代码使用现有的Action代理而不是自定义代理,但它每次都会创建一个Action委托对象(与第二个代码段不同)。 因此,您可以使用以下代码:

 private Action _delegateInstance = myMethod; //... Label1.Invoke(_delegateInstance , new Object[] {1, "This is the string"});