Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Методы Invoke, BeginInvoke, EndInvoke⇐ ПредыдущаяСтр 75 из 75
При многопоточном программировании на C# элементы интерфейса не относятся к общим ресурсам, доступным для всех потоков. Поток не имеет права доступа к элементу интерфейса, созданному в другом потоке. Это означает, что дочерние потоки, реализующие бизнес-логику, не имеют права " чтения" и " записи" в элементы управления интерфейса, созданные в основном потоке. Организация взаимодействия между потоками, использующими общие элементы интерфейса, требует своего рода маршалинга, когда объект одного потока передается элементу управления другого потока, проходя нужные стадии преобразования. Такой маршалинг можно реализовать, используя метод Invoke. Все элементы интерфейса обладают методом Invoke, наследуя его от класса Control. Метод перегружен и имеет две реализации: Invoke(Delegate); Invoke(Delegate, object[]); В обеих реализациях первый аргумент функционального типа (delegate) задает метод, принадлежащий потоку, в котором определен элемент интерфейса. Именно этот метод и будет выполнять операцию над элементом интерфейса. Если нет необходимости передавать методу информацию, то используется реализация Invoke с одним аргументом. В этом случае в качестве функционального типа можно использовать стандартный тип - класс MethodInvoker из пространства System.Windows.Forms. Рассмотрим пример вызова метода Invoke: myForm.Invoke(new MethodInvoker(myForm.SetVisions)); Здесь объект myForm, задающий форму, вызывает метод Invoke. В качестве фактического параметра ему передается метод SetVisions - метод без аргументов, соответствующий типу MethodInvoker. Метод SetVisions принадлежит тому же классу, что и объект myForm и потому может быть вызван этим объектом. Чаще всего, методу, работающему с элементом управления, необходимо передать информацию, так что метод, вызываемый в Invoke, может иметь один или несколько аргументов. В этом случае необходимо определить соответствующий функциональный тип - аналог MethodInvoker, создать метод - экземпляр этого типа, передать этот метод в качестве первого аргумента методу Invoke, а необходимые данные передать в качестве второго аргумента. Второй аргумент метода Invoke задается массивом объектов, таким образом можно передать значения всех требуемых аргументов методу, работающему с элементом управления. Рассмотрим пример, когда элементу управления нужно передать строку текста - объект типа string. Объявим, прежде всего, соответствующий функциональный тип: public delegate void Delegate_Void_String(string par); //Определим теперь экземпляр этого типа и свяжем с ним требуемый метод: public Delegate_Void_String myDelegate; myDelegate = AddList; Метод AddList, добавляющий строку в элемент управления ListBox, определен следующим образом: void AddList(string item) { listBoxValues.Items.Add(item); } Теперь в другом потоке можем добавить данные в элемент управления, вызвав метод Invoke следующим образом: correctForm.Invoke(correctForm.myDelegate, new object[] { res }); Здесь res задает передаваемую строку данных, добавляемую в список элемента управления. Метод Invoke является синхронным методом, ожидающим завершения операции над элементом управления. Методы BeginInvoke и EndInvoke обеспечивают асинхронное выполнение. По принципу организации передачи информации они схожи, и я не буду останавливаться подробно на их рассмотрении.
|