Control.Invoke () и Control.BeginInvoke () - Где хранятся прошлые параметры?Как это утилизируется? - PullRequest
3 голосов
/ 18 августа 2011

Я много читал о Control.Invoke и Control.BeginInvoke и понимаю, что Invoke похож на SendMessage(), а BeginInvoke похож на PostMessage(), но я не понимаю, где список параметров прошел через new object[] { arg, arg, arg, ...} хранится. Во время обычного вызова параметры помещаются в стек и извлекаются из вызываемой функции, затем кадр вызова восстанавливается из стека после выхода, я предполагаю, что освобождаю любые ссылки на любые объекты кучи, позволяя их собирать. Итак, где хранится дата сдвинутого стека для Invoke / BeginInvoke? Как он удаляется после вызова метода exits?

Кроме того, я успешно вызвал метод управления без загрузки нового массива объектов с параметрами передачи. Почему это работает? Еще лучше, поскольку он работает, почему все примеры, которые я когда-либо видел, показывают это с новым массивом объектов?

Это то, что я всегда видел и использовал:

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

Но это тоже работает:

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

Любая информация и комментарии всегда приветствуются ...

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 18 августа 2011

object[], содержащий параметры, хранится внутри метода BeginInvoke, в то время как он асинхронно вызывает целевой делегат. Ссылка на массив освобождается после завершения асинхронного вызова, что позволяет собирать массив и его содержимое (при условии, что они недоступны иным образом).

Форма BeginInvoke(FormReceiveEvent, Event, Arg1, Arg2, Arg3); работает, потому что второй параметр BeginInvoke определяется как params object[]. Это означает, что если вы явно не создадите массив, компилятор сделает это за вас. Таким образом, два вызова идентичны с точки зрения поведения во время выполнения.

<Ч />

Замечание по терминологии: в контексте .Net сказать, что объект «расположен», обычно означает, что объект реализует IDisposable и что его метод IDisposable.Dispose был вызван. В контексте Control.BeginInvoke и Control.Invoke этого не происходит.

После завершения асинхронного вызова ссылка на object[] освобождается, чтобы ее можно было собрать, но если какой-либо из ее членов реализует IDisposable, метод IDisposable.Dispose вызывается , а не . Ресурсы объекта не будут освобождены до тех пор, пока он не будет собран (или кто-то еще не уничтожит его).

0 голосов
/ 18 августа 2011

При передаче какого-либо объекта в Control.Invoke или Control.BeginInvoke вы передаете параметры в «метод» , он ничем не отличается от передачи параметров любому методу. Однако, если вас интересует реализация Invoke и BeginInvoke, вы можете проверить это в этом answer .

Для второй части вопроса подпись BeginInvoke:

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

Итак, вы спрашиваете о ключевом слове params , которое является специальным ключевым словом, которое позволяет передавать n аргументы или массив определенного типа в метод.

Ключевое слово params позволяет указать параметр метода, который принимает переменное число аргументов. Вы можете отправить разделенный запятыми список аргументов типа, указанного в объявлении параметра, или массив аргументов указанного типа. Вы также не можете отправлять аргументы.

0 голосов
/ 18 августа 2011

Не всегда верно, что переданный параметр хранится в стеке.Только если его значение сохранено.В противном случае ссылка хранится там, смотря на кучу этого типа ссылки.

В этом случае то же самое сохраняется.И разница между массивом объектов и передачей в виде отдельного массива, я думаю, его распределение по стеку.Если вы передаете их отдельно, выделяется больше стекового пространства.Где как, в стеке выделяется ссылка, указывающая на N объектов массива в куче.

Не стесняйтесь исправлять меня.

...