繁体   English   中英

Control.Invoke()和Control.BeginInvoke() - 过去的参数存储在哪里? 怎么处理?

[英]Control.Invoke() and Control.BeginInvoke() - Where are the past parameters stored? How is it disposed?

我已经做了很多关于Control.Invoke和Control.BeginInvoke的阅读,并了解Invoke就像SendMessage()BeginInvoke就像PostMessage() ,但我不明白参数列表通过new object[] { arg, arg, arg, ...}传递的位置new object[] { arg, arg, arg, ...}被存储。 在传统调用期间,参数被推送到堆栈并在被调用函数内弹出,然后在退出后从堆栈中恢复调用帧,我假设释放对任何堆对象的任何引用,允许它们被收集。 那么, Invoke / BeginInvoke的推送堆栈日期存储在哪里? 一旦调用退出方法,它是如何处理的?

此外,我已成功调用控制方法,而无需使用传递参数加载新的对象数组。 为什么会这样? 更好的是,既然它确实有效,为什么我见过的所有例子都用新的对象数组显示它?

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

BeginInvoke(FormReceiveEvent, new object[] { Event, Arg1, Arg2, Arg3 });

但这也有效:

BeginInvoke(FormReceiveEvent, Event, Arg1, Arg2, Arg3);

任何信息和评论总是受到赞赏......

提前致谢。

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

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


关于术语的说明:在.Net的上下文中,说对象被“处理”通常意味着该对象实现了IDisposable并且其IDisposable.Dispose方法被调用。 Control.BeginInvokeControl.Invoke的上下文中,这不会发生。

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

传递的参数存储在堆栈中并不总是正确的。 只有它的值类型存储。 另一方面,ref存储在那里查看ref类型的堆。

在这种情况下,同样也很好。 并且差异bw对象数组并作为单独的数组传递,我猜它在堆栈上的分配。 如果你单独传递它们,则会分配更多的堆栈空间。 其中,ref在堆栈中分配,指向堆中的N个数组对象。

随意纠正我。

将一些对象传递给Control.InvokeControl.BeginInvoke ,您将参数传递给“方法” ,它与将参数传递给任何方法没有什么不同。 但是,如果您对InvokeBeginInvoke实现BeginInvoke ,可以在此答案中进行检查。

对于问题的第二部分, BeginInvoke的签名是:

BeginInvoke(Delegate method, params object[] args);

所以你问的是params关键字,它是一个特殊的关键字,允许你将n参数或特定类型的数组传递给方法。

params关键字允许您指定采用可变数量参数的方法参数。 您可以发送以逗号分隔的参数声明中指定类型的参数列表,或者指定类型的参数数组。 你也可以不发送任何参数。

暂无
暂无

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

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