Поделиться через


Control.Invoke Метод

Определение

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

Перегрузки

Invoke(Action)

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

Invoke(Delegate)

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

Invoke(Delegate, Object[])

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

Invoke<T>(Func<T>)

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

Invoke(Action)

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

public:
 void Invoke(Action ^ method);
public void Invoke (Action method);
member this.Invoke : Action -> unit
Public Sub Invoke (method As Action)

Параметры

method
Action

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

Применяется к

Invoke(Delegate)

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

public:
 System::Object ^ Invoke(Delegate ^ method);
public object Invoke (Delegate method);
member this.Invoke : Delegate -> obj
Public Function Invoke (method As Delegate) As Object

Параметры

method
Delegate

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

Возвращаемое значение

Значение, возвращаемое вызываемым делегатом, или значение null, если делегат не возвращает никакого значения.

Примеры

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

/*
The following example demonstrates the 'Invoke(Delegate*)' method of 'Control class.
A 'ListBox' and a 'Button' control are added to a form, containing a delegate
which encapsulates a method that adds items to the listbox. This function is executed
on the thread that owns the underlying handle of the form. When user clicks on button
the above delegate is executed using 'Invoke' method.
*/

#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
using namespace System::Threading;

public ref class MyFormControl: public Form
{
public:
   delegate void AddListItem();
   AddListItem^ myDelegate;

private:
   Button^ myButton;
   Thread^ myThread;
   ListBox^ myListBox;

public:
   MyFormControl();
   void AddListItemMethod()
   {
      String^ myItem;
      for ( int i = 1; i < 6; i++ )
      {
         myItem = "MyListItem {0}",i;
         myListBox->Items->Add( myItem );
         myListBox->Update();
         Thread::Sleep( 300 );
      }
   }

private:
   void Button_Click( Object^ /*sender*/, EventArgs^ /*e*/ )
   {
      myThread = gcnew Thread( gcnew ThreadStart( this, &MyFormControl::ThreadFunction ) );
      myThread->Start();
   }

   void ThreadFunction();
};


// The following code assumes a 'ListBox' and a 'Button' control are added to a form,
// containing a delegate which encapsulates a method that adds items to the listbox.
public ref class MyThreadClass
{
private:
   MyFormControl^ myFormControl1;

public:
   MyThreadClass( MyFormControl^ myForm )
   {
      myFormControl1 = myForm;
   }

   void Run()
   {
      // Execute the specified delegate on the thread that owns
      // 'myFormControl1' control's underlying window handle.
      myFormControl1->Invoke( myFormControl1->myDelegate );
   }
};


MyFormControl::MyFormControl()
{
   myButton = gcnew Button;
   myListBox = gcnew ListBox;
   myButton->Location = Point( 72, 160 );
   myButton->Size = System::Drawing::Size( 152, 32 );
   myButton->TabIndex = 1;
   myButton->Text = "Add items in list box";
   myButton->Click += gcnew EventHandler( this, &MyFormControl::Button_Click );
   myListBox->Location = Point( 48, 32 );
   myListBox->Name = "myListBox";
   myListBox->Size = System::Drawing::Size( 200, 95 );
   myListBox->TabIndex = 2;
   ClientSize = System::Drawing::Size( 292, 273 );
   array<Control^>^ temp0 = {myListBox,myButton};
   Controls->AddRange( temp0 );
   Text = " 'Control_Invoke' example";
   myDelegate = gcnew AddListItem( this, &MyFormControl::AddListItemMethod );
}

void MyFormControl::ThreadFunction()
{
   MyThreadClass^ myThreadClassObject = gcnew MyThreadClass( this );
   myThreadClassObject->Run();
}

int main()
{
   MyFormControl^ myForm = gcnew MyFormControl;
   myForm->ShowDialog();
}
/*
The following example demonstrates the 'Invoke(Delegate)' method of 'Control class.
A 'ListBox' and a 'Button' control are added to a form, containing a delegate
which encapsulates a method that adds items to the listbox. This function is executed
on the thread that owns the underlying handle of the form. When user clicks on button
the above delegate is executed using 'Invoke' method.


*/

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

   public class MyFormControl : Form
   {
      public delegate void AddListItem();
      public AddListItem myDelegate;
      private Button myButton;
      private Thread myThread;
      private ListBox myListBox;
      public MyFormControl()
      {
         myButton = new Button();
         myListBox = new ListBox();
         myButton.Location = new Point(72, 160);
         myButton.Size = new Size(152, 32);
         myButton.TabIndex = 1;
         myButton.Text = "Add items in list box";
         myButton.Click += new EventHandler(Button_Click);
         myListBox.Location = new Point(48, 32);
         myListBox.Name = "myListBox";
         myListBox.Size = new Size(200, 95);
         myListBox.TabIndex = 2;
         ClientSize = new Size(292, 273);
         Controls.AddRange(new Control[] {myListBox,myButton});
         Text = " 'Control_Invoke' example";
         myDelegate = new AddListItem(AddListItemMethod);
      }
      static void Main()
      {
         MyFormControl myForm = new MyFormControl();
         myForm.ShowDialog();
      }
      public void AddListItemMethod()
      {
         String myItem;
         for(int i=1;i<6;i++)
         {
            myItem = "MyListItem" + i.ToString();
            myListBox.Items.Add(myItem);
            myListBox.Update();
            Thread.Sleep(300);
         }
      }
      private void Button_Click(object sender, EventArgs e)
      {
         myThread = new Thread(new ThreadStart(ThreadFunction));
         myThread.Start();
      }
      private void ThreadFunction()
      {
         MyThreadClass myThreadClassObject  = new MyThreadClass(this);
         myThreadClassObject.Run();
      }
   }

// The following code assumes a 'ListBox' and a 'Button' control are added to a form, 
// containing a delegate which encapsulates a method that adds items to the listbox.

   public class MyThreadClass
   {
      MyFormControl myFormControl1;
      public MyThreadClass(MyFormControl myForm)
      {
         myFormControl1 = myForm;
      }

      public void Run()
      {
         // Execute the specified delegate on the thread that owns
         // 'myFormControl1' control's underlying window handle.
         myFormControl1.Invoke(myFormControl1.myDelegate);
      }
   }
' The following example demonstrates the 'Invoke(Delegate)' method of 'Control class.
' A 'ListBox' and a 'Button' control are added to a form, containing a delegate
' which encapsulates a method that adds items to the listbox. This function is executed
' on the thread that owns the underlying handle of the form. When user clicks on button
' the above delegate is executed using 'Invoke' method.

Imports System.Drawing
Imports System.Windows.Forms
Imports System.Threading

Public Class MyFormControl
   Inherits Form

   Delegate Sub AddListItem()
   Public myDelegate As AddListItem
   Private myButton As Button
   Private myThread As Thread
   Private myListBox As ListBox

   Public Sub New()
      myButton = New Button()
      myListBox = New ListBox()
      myButton.Location = New Point(72, 160)
      myButton.Size = New Size(152, 32)
      myButton.TabIndex = 1
      myButton.Text = "Add items in list box"
      AddHandler myButton.Click, AddressOf Button_Click
      myListBox.Location = New Point(48, 32)
      myListBox.Name = "myListBox"
      myListBox.Size = New Size(200, 95)
      myListBox.TabIndex = 2
      ClientSize = New Size(292, 273)
      Controls.AddRange(New Control() {myListBox, myButton})
      Text = " 'Control_Invoke' example"
      myDelegate = New AddListItem(AddressOf AddListItemMethod)
   End Sub

   Shared Sub Main()
      Dim myForm As New MyFormControl()
      myForm.ShowDialog()
   End Sub

   Public Sub AddListItemMethod()
      Dim myItem As String
      Dim i As Integer
      For i = 1 To 5
         myItem = "MyListItem" + i.ToString()
         myListBox.Items.Add(myItem)
         myListBox.Update()
         Thread.Sleep(300)
      Next i
   End Sub

   Private Sub Button_Click(sender As Object, e As EventArgs)
      myThread = New Thread(New ThreadStart(AddressOf ThreadFunction))
      myThread.Start()
   End Sub

   Private Sub ThreadFunction()
      Dim myThreadClassObject As New MyThreadClass(Me)
      myThreadClassObject.Run()
   End Sub
End Class


' The following code assumes a 'ListBox' and a 'Button' control are added to a form, 
' containing a delegate which encapsulates a method that adds items to the listbox.
Public Class MyThreadClass
   Private myFormControl1 As MyFormControl

   Public Sub New(myForm As MyFormControl)
      myFormControl1 = myForm
   End Sub

   Public Sub Run()
      ' Execute the specified delegate on the thread that owns
      ' 'myFormControl1' control's underlying window handle.
      myFormControl1.Invoke(myFormControl1.myDelegate)
   End Sub

End Class

Комментарии

Делегаты похожи на указатели функций в языках C или C++. Делегаты инкапсулируют ссылку на метод внутри объекта делегата. Затем объект делегата можно передать в код, который вызывает указанный метод, и вызываемый метод может быть неизвестен во время компиляции. В отличие от указателей функций в C или C++, делегаты являются объектно-ориентированными, типобезопасны и более безопасными.

Метод Invoke выполняет поиск родительской цепочки элемента управления, пока не найдет элемент управления или форму с дескриптором окна, если базовый дескриптор окна текущего элемента управления еще не существует. Если соответствующий дескриптор Invoke не найден, метод вызовет исключение. Исключения, возникающие во время вызова, будут распространяться обратно вызывающей стороне.

Примечание

В дополнение к свойству InvokeRequired есть четыре метода в элементе управления, которые являются потокобезопасны: Invoke, BeginInvoke, EndInvokeи CreateGraphics , если дескриптор для элемента управления уже создан. Вызов CreateGraphics до создания дескриптора элемента управления в фоновом потоке может привести к недопустимым вызовам между потоками. Для всех остальных вызовов методов следует использовать один из методов invoke для маршалинга вызова в поток элемента управления.

Делегат может быть экземпляром EventHandler, в этом случае параметр sender будет содержать этот элемент управления, а параметр события — EventArgs.Empty. Делегат также может быть экземпляром MethodInvokerили любым другим делегатом, принимаюющим список параметров void. Вызов делегата EventHandler или MethodInvoker будет выполняться быстрее, чем вызов делегата другого типа.

Примечание

Если поток, который должен обрабатывать сообщение, больше не активен, может возникнуть исключение.

См. также раздел

Применяется к

Invoke(Delegate, Object[])

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

public:
 virtual System::Object ^ Invoke(Delegate ^ method, cli::array <System::Object ^> ^ args);
public:
 virtual System::Object ^ Invoke(Delegate ^ method, ... cli::array <System::Object ^> ^ args);
public object Invoke (Delegate method, object[] args);
public object Invoke (Delegate method, params object[] args);
public object Invoke (Delegate method, params object?[]? args);
abstract member Invoke : Delegate * obj[] -> obj
override this.Invoke : Delegate * obj[] -> obj
Public Function Invoke (method As Delegate, args As Object()) As Object
Public Function Invoke (method As Delegate, ParamArray args As Object()) As Object

Параметры

method
Delegate

Делегат метода, принимающий параметры, количество и тип которых являются такими же, что и в параметре args.

args
Object[]

Массив объектов, передаваемых в качестве аргументов указанному методу. Данный параметр может иметь значение null, если метод не принимает аргументы.

Возвращаемое значение

Объект Object, содержащий возвращаемое значение от вызываемого делегата, или значение null, если делегат не имеет возвращаемого значения.

Реализации

Примеры

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

using namespace System;
using namespace System::Drawing;
using namespace System::ComponentModel;
using namespace System::Windows::Forms;
using namespace System::Threading;
ref class MyFormControl: public Form
{
public:
   delegate void AddListItem( String^ myString );
   AddListItem^ myDelegate;

private:
   Button^ myButton;
   Thread^ myThread;
   ListBox^ myListBox;

public:
   MyFormControl();
   void AddListItemMethod( String^ myString );

private:
   void Button_Click( Object^ sender, EventArgs^ e );
   void ThreadFunction();
};

ref class MyThreadClass
{
private:
   MyFormControl^ myFormControl1;

public:
   MyThreadClass( MyFormControl^ myForm )
   {
      myFormControl1 = myForm;
   }

   String^ myString;
   void Run()
   {
      for ( int i = 1; i <= 5; i++ )
      {
         myString = String::Concat( "Step number ", i, " executed" );
         Thread::Sleep( 400 );
         
         // Execute the specified delegate on the thread that owns
         // 'myFormControl1' control's underlying window handle with
         // the specified list of arguments.
         array<Object^>^myStringArray = {myString};
         myFormControl1->Invoke( myFormControl1->myDelegate, myStringArray );

      }
   }

};

MyFormControl::MyFormControl()
{
   myButton = gcnew Button;
   myListBox = gcnew ListBox;
   myButton->Location = Point(72,160);
   myButton->Size = System::Drawing::Size( 152, 32 );
   myButton->TabIndex = 1;
   myButton->Text = "Add items in list box";
   myButton->Click += gcnew EventHandler( this, &MyFormControl::Button_Click );
   myListBox->Location = Point(48,32);
   myListBox->Name = "myListBox";
   myListBox->Size = System::Drawing::Size( 200, 95 );
   myListBox->TabIndex = 2;
   ClientSize = System::Drawing::Size( 292, 273 );
   array<Control^>^formControls = {myListBox,myButton};
   Controls->AddRange( formControls );
   Text = " 'Control_Invoke' example ";
   myDelegate = gcnew AddListItem( this, &MyFormControl::AddListItemMethod );
}

void MyFormControl::AddListItemMethod( String^ myString )
{
   myListBox->Items->Add( myString );
}

void MyFormControl::Button_Click( Object^ /*sender*/, EventArgs^ /*e*/ )
{
   myThread = gcnew Thread( gcnew ThreadStart( this, &MyFormControl::ThreadFunction ) );
   myThread->Start();
}

void MyFormControl::ThreadFunction()
{
   MyThreadClass^ myThreadClassObject = gcnew MyThreadClass( this );
   myThreadClassObject->Run();
}

int main()
{
   MyFormControl^ myForm = gcnew MyFormControl;
   myForm->ShowDialog();
}
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

   public class MyFormControl : Form
   {
      public delegate void AddListItem(String myString);
      public AddListItem myDelegate;
      private Button myButton;
      private Thread myThread;
      private ListBox myListBox;
      public MyFormControl()
      {
         myButton = new Button();
         myListBox = new ListBox();
         myButton.Location = new Point(72, 160);
         myButton.Size = new Size(152, 32);
         myButton.TabIndex = 1;
         myButton.Text = "Add items in list box";
         myButton.Click += new EventHandler(Button_Click);
         myListBox.Location = new Point(48, 32);
         myListBox.Name = "myListBox";
         myListBox.Size = new Size(200, 95);
         myListBox.TabIndex = 2;
         ClientSize = new Size(292, 273);
         Controls.AddRange(new Control[] {myListBox,myButton});
         Text = " 'Control_Invoke' example ";
         myDelegate = new AddListItem(AddListItemMethod);
      }
      static void Main()
      {
         MyFormControl myForm = new MyFormControl();
         myForm.ShowDialog();
      }
      public void AddListItemMethod(String myString)
      {
            myListBox.Items.Add(myString);
      }
      private void Button_Click(object sender, EventArgs e)
      {
         myThread = new Thread(new ThreadStart(ThreadFunction));
         myThread.Start();
      }
      private void ThreadFunction()
      {
         MyThreadClass myThreadClassObject  = new MyThreadClass(this);
         myThreadClassObject.Run();
      }
   }
   public class MyThreadClass
   {
      MyFormControl myFormControl1;
      public MyThreadClass(MyFormControl myForm)
      {
         myFormControl1 = myForm;
      }
      String myString;

      public void Run()
      {

         for (int i = 1; i <= 5; i++)
         {
            myString = "Step number " + i.ToString() + " executed";
            Thread.Sleep(400);
            // Execute the specified delegate on the thread that owns
            // 'myFormControl1' control's underlying window handle with
            // the specified list of arguments.
            myFormControl1.Invoke(myFormControl1.myDelegate,
                                   new Object[] {myString});
         }
      }
   }
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Threading

Public Class MyFormControl
   Inherits Form

   Delegate Sub AddListItem(myString As String)
   Public myDelegate As AddListItem
   Private myButton As Button
   Private myThread As Thread
   Private myListBox As ListBox

   Public Sub New()
      myButton = New Button()
      myListBox = New ListBox()
      myButton.Location = New Point(72, 160)
      myButton.Size = New Size(152, 32)
      myButton.TabIndex = 1
      myButton.Text = "Add items in list box"
      AddHandler myButton.Click, AddressOf Button_Click
      myListBox.Location = New Point(48, 32)
      myListBox.Name = "myListBox"
      myListBox.Size = New Size(200, 95)
      myListBox.TabIndex = 2
      ClientSize = New Size(292, 273)
      Controls.AddRange(New Control() {myListBox, myButton})
      Text = " 'Control_Invoke' example "
      myDelegate = New AddListItem(AddressOf AddListItemMethod)
   End Sub

   Shared Sub Main()
      Dim myForm As New MyFormControl()
      myForm.ShowDialog()
   End Sub

   Public Sub AddListItemMethod(myString As String)
      myListBox.Items.Add(myString)
   End Sub

   Private Sub Button_Click(sender As Object, e As EventArgs)
      myThread = New Thread(New ThreadStart(AddressOf ThreadFunction))
      myThread.Start()
   End Sub

   Private Sub ThreadFunction()
      Dim myThreadClassObject As New MyThreadClass(Me)
      myThreadClassObject.Run()
   End Sub
End Class

Public Class MyThreadClass
   Private myFormControl1 As MyFormControl

   Public Sub New(myForm As MyFormControl)
      myFormControl1 = myForm
   End Sub
   Private myString As String

   Public Sub Run()

      Dim i As Integer
      For i = 1 To 5
         myString = "Step number " + i.ToString() + " executed"
         Thread.Sleep(400)
         ' Execute the specified delegate on the thread that owns
         ' 'myFormControl1' control's underlying window handle with
         ' the specified list of arguments.
         myFormControl1.Invoke(myFormControl1.myDelegate, New Object() {myString})
      Next i

   End Sub
End Class

Комментарии

Делегаты похожи на указатели функций в языках C или C++. Делегаты инкапсулируют ссылку на метод внутри объекта делегата. Затем объект делегата можно передать в код, который вызывает указанный метод, и вызываемый метод может быть неизвестен во время компиляции. В отличие от указателей функций в C или C++, делегаты являются объектно-ориентированными, типобезопасны и более безопасными.

Если дескриптор элемента управления еще не существует, этот метод выполняет поиск в родительской цепочке элемента управления, пока не найдет элемент управления или форму с дескриптором окна. Если соответствующий дескриптор не найден, этот метод создает исключение. Исключения, возникающие во время вызова, будут распространяться обратно вызывающей стороне.

Примечание

В дополнение к свойству InvokeRequired есть четыре метода в элементе управления, которые являются потокобезопасны: Invoke, BeginInvoke, EndInvokeи CreateGraphics , если дескриптор для элемента управления уже создан. Вызов CreateGraphics до создания дескриптора элемента управления в фоновом потоке может привести к недопустимым вызовам между потоками. Для всех остальных вызовов методов следует использовать один из методов invoke для маршалинга вызова в поток элемента управления.

Делегат может быть экземпляром EventHandler, в этом случае параметр sender будет содержать этот элемент управления, а параметр события — EventArgs.Empty. Делегат также может быть экземпляром MethodInvokerили любым другим делегатом, принимаюющим список параметров void. Вызов делегата EventHandler или MethodInvoker будет выполняться быстрее, чем вызов делегата другого типа.

Примечание

Если поток, который должен обрабатывать сообщение, больше не активен, может возникнуть исключение.

См. также раздел

Применяется к

Invoke<T>(Func<T>)

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

public:
generic <typename T>
 T Invoke(Func<T> ^ method);
public T Invoke<T> (Func<T> method);
member this.Invoke : Func<'T> -> 'T
Public Function Invoke(Of T) (method As Func(Of T)) As T

Параметры типа

T

Тип возвращаемого methodзначения .

Параметры

method
Func<T>

Функция, вызываемая в контексте потока элемента управления.

Возвращаемое значение

T

Возвращаемое значение вызываемой функции.

Применяется к