C# Control.Invoke()和Control.BeginInvoke()-过去的参数存储在哪里?如何处置?

C# Control.Invoke()和Control.BeginInvoke()-过去的参数存储在哪里?如何处置?,c#,.net,invoke,begininvoke,C#,.net,Invoke,Begininvoke,我读了很多关于Control.Invoke和Control.BeginInvoke的书,了解到Invoke类似于SendMessage(),BeginInvoke类似于PostMessage(),但我不知道通过新对象[]{arg arg,arg,…}传递的参数列表存储在哪里。在常规调用期间,参数被推送到堆栈并在被调用函数中弹出,然后在退出后从堆栈中恢复调用帧,我假设释放对任何堆对象的引用,允许收集它们。那么,Invoke/BeginInvoke的推送堆栈日期存储在哪里?一旦调用的方法退出,它将如

我读了很多关于Control.Invoke和Control.BeginInvoke的书,了解到Invoke类似于
SendMessage()
BeginInvoke
类似于
PostMessage()
,但我不知道通过
新对象[]{arg arg,arg,…}
传递的参数列表存储在哪里。在常规调用期间,参数被推送到堆栈并在被调用函数中弹出,然后在退出后从堆栈中恢复调用帧,我假设释放对任何堆对象的引用,允许收集它们。那么,
Invoke
/
BeginInvoke
的推送堆栈日期存储在哪里?一旦调用的方法退出,它将如何处理

此外,我还成功地调用了一个控制方法,而无需加载带有pass参数的新对象数组。为什么会这样?更好的是,既然它确实有效,为什么我见过的所有示例都会用一个新的对象数组来显示它呢

这是我一直看到和使用的:

BeginInvoke(FormReceiveEvent, new object[] { Event, Arg1, Arg2, Arg3 });
但这也行得通:

BeginInvoke(FormReceiveEvent, Event, Arg1, Arg2, Arg3);
任何信息和评论都将不胜感激


提前感谢。

包含参数的
对象[]
由BeginInvoke方法在内部存储,同时它异步调用目标委托。异步调用完成后,将释放对数组的引用,从而允许收集数组及其内容(假设它们无法访问)

BeginInvoke(FormReceiveEvent,Event,Arg1,Arg2,Arg3)
form之所以有效,是因为
BeginInvoke
的第二个参数定义为。这意味着,如果不显式创建数组,编译器将为您创建数组。因此,这两个调用在运行时行为方面是相同的


术语说明:在.Net上下文中,如果说对象是“Dispose”的,通常意味着该对象实现了
IDisposable
,并且调用了它的
IDisposable.Dispose
方法。在
Control.BeginInvoke
Control.Invoke
的上下文中,这不会发生


异步调用完成后,将释放对
对象[]
的引用,以便收集该对象,但如果其任何成员实现了
IDisposable
,则不会调用
IDisposable.Dispose
方法。对象的资源在被收集(或其他人处理)之前不会被释放。

传递的参数存储在堆栈上并不总是正确的。仅当其valuetype已存储时。另一方面,一个ref存储在那里,查看该ref类型的堆

在这种情况下,同样适用。区别于b.w对象数组和作为单个数组传递,我猜这是堆栈上的分配。如果单独传递它们,则会分配更多的堆栈空间。其中,在堆栈中分配一个ref,指向堆中N个数组对象


请随意更正。

当将某个对象传递给
控件。调用
控件。开始调用
,您将参数传递给“方法”,这与将参数传递给任何方法没有什么不同。但是,如果您对
Invoke
BeginInvoke
实现很感兴趣,您可以在这里检查它

对于问题的第二部分,
BeginInvoke
的含义是:

BeginInvoke(Delegate method, params object[] args);
所以您询问的是关键字,它是一个特殊的关键字,允许您将
n
参数或特定类型的数组传递给方法

params关键字允许您指定一个方法参数,该参数接受可变数量的参数。 可以发送参数声明中指定类型的逗号分隔参数列表,也可以发送指定类型的参数数组。您也可以不发送参数


值类型不需要在堆栈上传递。jitter可能会选择注册它们。别介意eric,我在读了这篇文章后得到了你的,我可以说ValueType的存储主要在堆栈上,但很少在其他可能的地方。NET实现秘密?要点很好。对不起,我们误用了dispose。因此,只要不再存在对对象的引用,并且发生GC,那么如果实现IDisposble,它将调用dispose?再次感谢。@CCS:如果实现
IDisposable
的对象包含任何非托管资源,那么这些资源也应该由对象的终结器释放,因此如果对象在收集之前未被释放,它们仍然会被释放。通常的模式是使用
Dispose(bool)
方法,并且
IDisposable.Dispose
方法调用
Dispose(true)
,终结器调用
Dispose(false)