Control.Invoke 方法
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
在拥有控件的基础窗口句柄的线程上执行委托。
重载
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 可能会导致非法跨线程调用。 对于所有其他方法调用,应使用其中一个调用方法封送对控件线程的调用。
委托可以是 EventHandler的实例,在这种情况下,发送方参数将包含此控件,事件参数将包含 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 可能会导致非法跨线程调用。 对于所有其他方法调用,应使用其中一个调用方法封送对控件线程的调用。
委托可以是 EventHandler的实例,在这种情况下,参数将取决于 args
值:
- 如果未传递任何参数,发送方参数将包含此控件,事件参数将包含 EventArgs.Empty。
- 传递单个参数时,发送方参数将包含第一个参数元素,事件参数将包含 EventArgs.Empty。
- 如果传递了多个参数,发送方参数将包含来自
args
的第一个元素,EventArgs 参数将包含第二个元素。
对 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>
在控件的线程上下文中调用的函数。
返回
正在调用的函数的返回值。