Control.Invoke() 和 Control.BeginInvoke() - 过去的参数存储在哪里?它是如何处置的?
我已经阅读了大量有关 Control.Invoke 和 Control.BeginInvoke 的内容,并了解 Invoke 就像 SendMessage()
,而 BeginInvoke
就像 PostMessage(),但我不明白通过
new object[] { arg, arg, arg, ...}
传递的参数列表存储在哪里。在传统调用期间,参数被推送到堆栈并在被调用函数中弹出,然后退出后从堆栈中恢复调用帧,我假设释放对任何堆对象的任何引用,从而允许收集它们。那么,Invoke
/BeginInvoke
的推送堆栈日期存储在哪里?一旦调用的方法退出,它如何被处理?
此外,我已成功调用控制方法,而无需使用传递参数加载新的对象数组。为什么这会起作用?更好的是,既然它确实有效,为什么我见过的所有示例都会用新的对象数组来显示它?
这是我一直看到和使用的:
BeginInvoke(FormReceiveEvent, new object[] { Event, Arg1, Arg2, Arg3 });
但这也有效:
BeginInvoke(FormReceiveEvent, Event, Arg1, Arg2, Arg3);
任何信息和评论总是值得赞赏......
提前致谢。
I have done a lot of reading about Control.Invoke and Control.BeginInvoke and understand that Invoke is like SendMessage()
and BeginInvoke
is like PostMessage()
, but I do not understand where the parameter list passed via new object[] { arg, arg, arg, ...}
is stored. During a conventional call, parameters are pushed to the stack and popped within the called function, then the call frame is recovered from the stack after exit, I assume releasing any references to any heap objects, allowing them to be collected. So, where is the pushed stack date for Invoke
/BeginInvoke
stored? How does it get disposed once the method called exits?
Also, I have successfully invoked a control method without loading a new object array with the pass parameters. Why would this work? Better yet, since it does work, why would all the examples I have ever seen show it with a new object array?
This is what I have always seen and used:
BeginInvoke(FormReceiveEvent, new object[] { Event, Arg1, Arg2, Arg3 });
But this works too:
BeginInvoke(FormReceiveEvent, Event, Arg1, Arg2, Arg3);
Any information and comments are always appreciated...
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
包含参数的
object[]
由 BeginInvoke 方法在异步调用目标委托时在内部存储。一旦异步调用完成,就会释放对数组的引用,从而允许收集数组及其内容(假设它们无法通过其他方式访问)。BeginInvoke(FormReceiveEvent, Event, Arg1, Arg2, Arg3);
表单可以正常工作,因为BeginInvoke
的第二个参数定义为参数对象[]
。这意味着如果您没有显式创建数组,编译器将为您创建数组。因此,这两个调用在运行时行为方面是相同的。关于术语的注释:在 .Net 的上下文中,说一个对象被“处置”通常意味着该对象实现了 IDisposable 且它的 IDisposable.Dispose 方法得到了叫。在
Control.BeginInvoke
和Control.Invoke
的上下文中,这种情况不会发生。异步调用完成后,对
object[]
的引用将被释放,以便可以收集它,但如果其任何成员实现IDisposable
,则IDisposable.未调用 Dispose
方法。对象的资源在被收集(或其他人处置它)之前不会被释放。The
object[]
containing the parameters is stored internally by the BeginInvoke method while it asynchronously invokes the target delegate. The reference to the array is released once the asynchronous call completes, allowing the array and its contents (assuming they are not otherwise reachable) to be collected.The
BeginInvoke(FormReceiveEvent, Event, Arg1, Arg2, Arg3);
form works because the second parameter toBeginInvoke
is defined asparams object[]
. This means that if you don't explicitly create an array, the compiler will do it for you. Therefore, the two calls are identical in terms of runtime behaviour.A note on terminology: in the context of .Net, to say that an object is "disposed" typically means that the object implements
IDisposable
and that itsIDisposable.Dispose
method got called. In the context ofControl.BeginInvoke
andControl.Invoke
, that does not happen.After the asynchronous call finishes, the reference to the
object[]
is released so it can be collected, but if any of its members implementIDisposable
, theIDisposable.Dispose
method is not called. The object's resources will not be released until it is collected (or someone else disposes it).传递的参数并不总是存储在堆栈上。仅当其值类型已存储时。否则,引用存储在那里,查看该引用类型的堆。
在这种情况下,这同样适用。区别 bw 对象数组和作为单独数组传递,我猜它是堆栈上的分配。如果单独传递它们,则会分配更多堆栈空间。其中,在堆栈中分配一个引用,指向堆中的 N 个数组对象。
请随时纠正我。
Not always its true that a passed param is stored on stack. Only if its valuetype its stored. Other wise a ref is stored there looking at heap for that ref type.
In this case, the same holds good too. And difference b.w object array and passing as individual array, i guess its the allocation on stack. If you pass them seperately more stack space is allocated. Where as, a ref is allocated in stack pointing out to N number of array objects in heap.
Feel free to correct me.
当将某个对象传递给
Control.Invoke
或Control.BeginInvoke
时,您将参数传递给“方法”,这与将参数传递给任何方法。但是,如果您对Invoke
和BeginInvoke
实现感到好奇,您可以在此 答案。对于问题的第二部分,
BeginInvoke
的签名是:所以您正在询问params 关键字,这是一个特殊的关键字,允许您将
n
个参数或特定类型的数组传递给方法。When passing some object to
Control.Invoke
orControl.BeginInvoke
, you are passing a parameters to a "method", it is no different from passing parameters to any method. However if you curios about theInvoke
andBeginInvoke
implementation you can check it in this answer.For the second part of the question the signiture of
BeginInvoke
is:So you are asking about the params keyword, which is a special keyword that allow you to pass
n
arguments or array of specific type to method.