Практическое руководство. Управление элементами управления из потоков

Обновлен: Ноябрь 2007

Компонент BackgroundWorker заменяет метод BeginInvoke и расширяет его функциональные возможности; однако при необходимости исходный метод BeginInvoke можно сохранить для обеспечения обратной совместимости и использования в будущем. Дополнительные сведения см. в разделе Общие сведения о компоненте BackgroundWorker.

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

Однако в определенных обстоятельствах бывает необходимо вызывать методы элементов управления из потоков. Например, можно вызвать метод, который отключает кнопку или обновляет отображение формы в ответ на действия, выполненные потоком. В среде .NET Framework предусмотрены методы, которые можно без риска вызывать из любого потока для активизации методов, взаимодействующих с элементами управления из других потоков. Метод Invoke позволяет выполнять методы в элементах управления в синхронном режиме, тогда как метод BeginInvoke инициирует асинхронное выполнение. Для использования этих методов необходимо объявить объект-делегат с такой же подписью, что и у вызываемого метода. После этого можно вызвать метод Invoke или BeginInvoke любого элемента управления формы путем задания соответствующего делегата для вызываемого метода. Все необходимые параметры упаковываются в класс Object и передаются в метод.

Чтобы вызвать методы, влияющие на элементы управления, принадлежащие другим потокам, выполните следующие действия.

  1. Объявите объект-делегат с подписью, идентичной подписи вызываемого метода.

    В следующем примере показано объявление делегата с параметрами типа Integer и String.

    Public Delegate Sub myDelegate(ByVal anInteger as Integer, ByVal _
       aString as String)
    
    public delegate void myDelegate(int anInteger, string aString);
    
  2. Воспользуйтесь любым элементом управления, чтобы вызвать методы, которые воздействуют на элементы управления, принадлежащие другим потокам.

    757y83z4.alert_note(ru-ru,VS.90).gifПримечание.

    Необходимые для метода параметры (если таковые предусмотрены) можно задать в составе класса Object.

    • Если требуется инициировать методы в синхронном режиме, вызовите метод Control.Invoke.

      Label1.Invoke(New myDelegate(AddressOf myMethod), New _
         Object() {1, "This is the string"})
      
      Label1.Invoke(new myDelegate(myMethod), new Object[] {1,
         "This is the string"});
      
    • Если требуется инициировать методы асинхронно, вызовите метод Control.BeginInvoke.

      Label1.BeginInvoke(New myDelegate(AddressOf myMethod), _
         New Object() {1, "This is the string"})
      
      Label1.BeginInvoke(new myDelegate(myMethod), new 
      Object[] {1, "This is the string"});
      

См. также

Задачи

Пошаговое руководство. Разработка простого многопоточного компонента с использованием Visual Basic

Пошаговое руководство. Разработка простого многопоточного компонента с помощью Visual C#

Основные понятия

Обзор асинхронной модели, основанной на событиях

Ссылки

BackgroundWorker

Другие ресурсы

Многопоточность в компонентах