В чем разница между "call" и "invoke"?
В настоящее время я читаю книгу Дэниела М. Солиса под названием "Иллюстрированный C# 2010." Книга говорит:
"Когда метод вызывается или вызывается..."
В чем разница между этими двумя терминами?
9 ответов
Как заявил Майкл Тейлор на форуме MSDN в 2006 году:
В конечном итоге они идентичны. Разница заключается в производительности и преимуществах. Если вы вызываете метод напрямую, компилятор сгенерирует необходимый код для поиска начального адреса метода в виртуальной таблице объекта, поместит параметры в стек и вызовет метод. Среда выполнения в конечном счете отвечает за решение этой проблемы, поскольку виртуальная таблица может меняться в зависимости от используемого объекта. Высоко оптимизированы и очень быстры, учитывая современные процессоры. Это идеальный механизм для использования. Проблема в том, что вы должны знать во время компиляции тип ссылки, имя метода и его сигнатуру. Это формально известно как раннее связывание. Если информация о методе изменится, ваш код не скомпилируется. Обычно это не проблема, но иногда это важно. Это где invoke приходит.
Invoke обычно используется в коде пользовательского интерфейса. В коде пользовательского интерфейса фундаментальное правило Windows состоит в том, что вы можете взаимодействовать только с пользовательским интерфейсом в потоке, который создал пользовательский интерфейс. Поэтому, если вы хотите общаться с пользовательским интерфейсом во вторичном потоке (например, рабочем потоке), вы должны перенаправить вызов в правильный поток. Обратите внимание, что это относится и к событиям. Они действительно не более чем вызовы методов. Control.Invoke
метод, который наследуется всеми элементами управления WinForm, позволяет вызывать произвольный метод в потоке пользовательского интерфейса. Метод обрабатывает процесс маршалинга запроса в правильный поток, а затем вызывает метод Invoke. Это все еще поздняя привязка, даже если вы заранее знаете, какой метод вы хотите вызвать.
Из моего исследования (личного и неоплачиваемого), глядя на общий способ использования этих терминов в литературе по программированию и "в дикой природе", я обнаружил, что эти определения, кажется, соответствуют их использованию.
Выполнение относится к процессу выполнения кода. Точный метод не имеет значения, может быть скомпилирован или нет, с помощью компьютера или нет.
Применение / Приложение относится к привязке аргументов к функции. Заявка может быть как частичной, так и полной. Из мира функционального программирования, частичное приложение производит другую функцию с меньшим количеством параметров, в то время как полное приложение создает thunk. Thunks - это функции без параметров и могут помочь с "ленивой оценкой".
Invoking / Invocation относится к процессу, необходимому для планирования выполнения функции с ее полностью связанными аргументами. Такие системы включают передачу аргументов в стек и перенос ПК на новый адрес, размещение сообщений / объектов / функций / групповых сообщений в очереди для последующего выполнения или в различных других системах RPC. Точный механизм не имеет значения. Понятие планирования для будущего исполнения имеет значение. Вызов требует выполнения функции воли.
Колл наименее определен из всех. Обычно относится к комбинированному процессу полного применения функции с последующим ее вызовом, обычно с добавленной семантикой, что ваш код будет ожидать возвращаемого значения.
Также обратите внимание, что все эти термины являются субъективными с точки зрения текущего кода, который пишется. Вызов функции через вызов RPC вызывает ее только со стороны клиента. Со стороны сервера запрос имеет другую точку вызова, если функция даже имеет какое-либо "значение" как функция на стороне сервера.
Вызов функции - это когда вы сами вызываете функцию в программе. В то время как функция вызывается, когда она вызывается автоматически.
Например, рассмотрим эту программу:
struct s
{
int a,b,s;
s()
{
a=2;
b=3;
}
void sum()
{
s=a+b;
}
};
void main()
{
struct s obj; //line 1
obj.sum(); // line 2
}
Здесь, когда строка 1 выполняется, вызывается функция (конструктор, т.е. s). Когда строка 2 выполняется, вызывается функция sum.
источник: веб
Вызов метода - это термин, который обычно называют косвенным вызовом метода (функции) из-за проблем или трудностей в его непосредственном вызове.
Например, в контексте параллельного программирования: предположим, что два потока внутри одного прикладного пространства работают параллельно. Вызов общедоступного метода объекта, находящегося в другом потоке, вызывает исключение перекрестного вызова, потому что может возникнуть гонка. Решение - вызвать объект для выполнения метода и передать оставшуюся часть работы объекту для управления параллельными запросами.
Другой пример - когда у вас есть делегат, указывающий на метод где-то. Когда вы просите делегата вызвать этот (неизвестный) метод, вы вызываете метод для запуска.
Может быть, он просто считает термины "вызов" и "вызвать" синонимичными, и просто хочет упомянуть оба слова, потому что оба термина могут встречаться в дикой природе. Не было бы возможно использовать или в этом случае?
Когда вы выполняете метод напрямую в своем коде, он называется Calling. Когда кто-то другой выполняет его за вас, это вызов. Это то, что я понял изControl.Invoke
метод.
Я не думаю, что существуют какие-то разные официальные определения для обоих терминов (во всех областях программирования), все разные объяснения делаются самими разными разработчиками. Итак, я предпочитаю рассматривать оба термина одинаково.
"Вызвать", по-видимому, означает косвенный вызов метода через посреднический механизм. Я уверен, что точный смысл автора размывается. Но они, должно быть, пытаются описать другой способ вызова метода, иначе этот термин вообще бы не возник.
Кроме того, общее (некомпьютерное) определение "призывать" обычно означает обращение к высшей власти за помощью. Это означало бы попросить посредника о помощи в выполнении чего-либо.
просто "вызов" - это гарантия того, что метод будет принят; "вызов" - это когда мы просто просим, чтобы метод был принят в надлежащее время.
например, основной поток (GUI) может изменять элементы управления путем вызова, но когда у вас есть другой поток, который хочет изменить элементы управления, он просто просит основной поток сделать это, когда он будет готов