Какая сборка C # содержит Invoke?

Альтернативный вопрос: почему VS10 так жалуется на Invoke?

В моем непрекращающемся стремлении заставить мое приложение работать стать лучшим в мире программистом на C #, я решил, что потоки - это хорошо.

В MSDN есть полезная статья о выполнении потоковобезопасных вызовов элементов управления, но он (и, по-видимому, любая другая статья по этому поводу) косвенно ссылается на метод под названием Invoke. Иногда предпочтительнее даже BeginInvoke, который, как я прочитал, < / а>.

Все это было бы здорово, если бы я мог заставить визуальную студию распознавать Invoke. MSDN сообщает, что содержится в сборке System.Windows.Forms , но я уже "использую" это. Конечно, я тоже пробовал использовать System.Threading, но безуспешно.

Какие обручи мне нужно перепрыгнуть, чтобы invoke заработал?


person Tom Wright    schedule 24.06.2010    source источник
comment
Что вы имеете в виду, говоря, что Visual Studio распознает Invoke? Intellisense?   -  person Stefan Steinegger    schedule 24.06.2010
comment
Вы говорите о вызове метода для элемента управления, который был создан в другом потоке, чем текущий выполняющийся поток?   -  person Ryan Conrad    schedule 24.06.2010
comment
Когда вы станете лучшим в мире программистом на C #, вы, вероятно, поймете, что потоки - это очень плохо. Или, по крайней мере, явное управление потоками - это плохо.   -  person Eric Lippert    schedule 24.06.2010
comment
@Eric Вы задали другой вопрос: stackoverflow.com/questions/3110154/   -  person Tom Wright    schedule 24.06.2010


Ответы (6)


Invoke находится в Control. Т.е. Control.Invoke();

Невозможно вызвать Invoke напрямую, поскольку в System.Windows.Forms такого метода нет. Метод Invoke - это элемент управления.

Вот пример I сделано ранее:

public delegate void AddListViewItemCallBack(ListView control, ListViewItem item);
public static void AddListViewItem(ListView control, ListViewItem item)
{
    if (control.InvokeRequired)
    {
        AddListViewItemCallBack d = new AddListViewItemCallBack(AddListViewItem);
        control.Invoke(d, new object[] { control, item });
    }
    else
    {
        control.Items.Add(item);
    }
}
person djdd87    schedule 24.06.2010

Вам нужно вызвать Invoke для экземпляра того, что его содержит - если вы используете Windows Forms, это будет элемент управления:

control.Invoke(someDelegate);

или для кода внутри формы вы можете использовать неявную ссылку this:

Invoke(someDelegate);

Вам не нужно проходить какие-то особые обручи. Если Visual Studio жалуется, укажите ошибку компилятора и код, на который она жалуется. Здесь нет ничего особенного в Invoke.

person Jon Skeet    schedule 24.06.2010

Winform Invoke - это метод экземпляра Control - вам просто нужен экземпляр элемента управления (который во многих случаях может быть this). Например:

txtBox.Invoke(...);

К нему также можно получить доступ через интерфейс или контекст синхронизации, если вам нужна абстракция, но самый простой подход - обработать его в пользовательском интерфейсе через событие, и в этом случае элементы управления доступны для удобства.

person Marc Gravell    schedule 24.06.2010

Если вы действительно хотите стать лучшим в мире программистом на C #, вы должны усвоить, что потоки - это нехорошо, если они не используются правильно.

Обновление пользовательского интерфейса между потоками обычно является признаком того, что вы злоупотребляете потоками.

В любом случае, использовать using System.Windows.Forms недостаточно, нужно добавить его в ссылки. Щелкните правой кнопкой мыши References в проводнике проекта, затем Добавить ссылки и выберите System.Windows.Forms

person Morfildur    schedule 24.06.2010
comment
Спасибо! Ты пошел и сделал, что сбило меня с толку. (Вот еще один вопрос, на который вы, возможно, захотите ответить: stackoverflow.com/questions/3110154/) - person Tom Wright; 24.06.2010
comment
Обновление пользовательского интерфейса между потоками обычно является признаком того, что вы злоупотребляете потоками. Вау, это для меня в новинку. Итак, если я помещаю долгую операцию анализа в поток BG, чтобы пользовательский интерфейс оставался отзывчивым, но пользователь хотел бы быстро увидеть дополнительные результаты, поэтому мой поток BG периодически отправляет результаты обратно в поток пользовательского интерфейса, это злоупотребление? И теперь вы собираетесь раскрыть лучшее решение? - person Conrad Albrecht; 24.06.2010
comment
Да, это довольно просто: используйте события. BG Thread предоставляет событие, на которое пользовательский интерфейс может подписаться, то есть FileCopied, NumberCalculated и т. Д. Пользовательский интерфейс может подписаться на него, и фоновый рабочий все равно будет работать без изменений, если вы переключите свой код с winforms на WPF, реализуете многоязычный пользовательский интерфейс. , измените скучный диалог на необычный диалог и т. д. - person Morfildur; 24.06.2010
comment
@Conrad: у dbemerlin есть отличная точка зрения. Еще один способ подумать об этом: бизнес операции анализа - это анализ, а не пользовательский интерфейс. Не должно быть какой-либо логики для непосредственного обновления UI в функции анализа; это не его забота. Если функция анализа предлагает в качестве услуги обратный вызов для описания своего текущего состояния, отлично, это является ее проблемой. Какое влияние на пользовательский интерфейс этого обратного вызова может быть обработано кодом пользовательского интерфейса. - person Eric Lippert; 24.06.2010
comment
Хорошо, просто недопонимание смысла. На самом деле моя ветка BG действительно использует событие именно так, как вы, ребята, поддерживаете; для меня все еще звучит как обновление пользовательского интерфейса между потоками. Фактически, мое событие запускается в потоке BG (потому что это единственный поток, о котором знает метод запуска). Но событие запускает метод пользовательского интерфейса (который, следовательно, также выполняется в потоке BG), который затем должен вызывать другой метод пользовательского интерфейса в потоках. - person Conrad Albrecht; 25.06.2010

Invoke - это метод для объектов, обычно находящийся в элементах управления в библиотеке форм и некоторых асинхронных классах. Конечно, вам нужны определенные объекты, чтобы иметь возможность вызывать Invoke для этого элемента управления / класса.

person Femaref    schedule 24.06.2010

Предположительно, вы пытаетесь вызвать Invoke из класса (т.е. не из Form или Control). Переместите свой код из класса в форму или элемент управления, и вы увидите, что Invoke компилируется и работает правильно (строго говоря, ваш код должен ссылаться на this.Invoke, что делает источник метода понятным, но Invoke также будет работать, поскольку предполагается this).

person MusiGenesis    schedule 24.06.2010