当在一个不同于UI线程的后台线程中需要访问UI控件时,可以使用Invoke方法或BeginInvoke方法来实现跨线程访问控件。
以下是在WinForm中使用Control类的Invoke方法和BeginInvoke方法的示例:
使用 Invoke 方法:
// 假设有一个名为textBox1的TextBox控件
string text = "Hello, World!";
// 在后台线程中访问UI控件
Thread thread = new Thread(() =>
{
// 使用Invoke方法在UI线程上执行操作
textBox1.Invoke((MethodInvoker)(() =>
{
textBox1.Text = text;
}));
});
thread.Start();
使用BegainInvoke方法:
// 假设有一个名为label1的Label控件
string text = "Hello, World!";
// 在后台线程中访问UI控件
Thread thread = new Thread(() =>
{
// 使用BeginInvoke方法异步在UI线程上执行操作
label1.BeginInvoke((MethodInvoker)(() =>
{
label1.Text = text;
}));
});
thread.Start();
区别
在 C# 中,BeginInvoke 方法和 Invoke 方法都可以用于在 UI 线程上执行指定的操作,它们之间的区别主要在于执行方式和返回类型:
Invoke 方法:
- Invoke 方法是同步执行的,也就是说调用 Invoke 方法后,会等待执行完毕并返回结果后才会继续执行下面的代码。
- Invoke 方法的返回类型和委托方法的返回类型相同。
BeginInvoke 方法:
- BeginInvoke 方法是异步执行的,调用 BeginInvoke 方法后会立即返回,不会等待委托方法执行完毕。
- BeginInvoke 方法的返回类型为 IAsyncResult,可以通过 EndInvoke 方法获取委托方法的执行结果。
因此,如果希望在调用线程上等待委托方法执行完毕并获取结果时,可以使用 Invoke 方法;如果希望在调用线程上异步执行委托方法,并且不需要立刻获取结果,可以使用 BeginInvoke 方法。
MethodInvoker是什么东西
MethodInvoker 是一个委托,通常用于在 C# 中表示一个不带参数且无返回值的方法或操作。它通常用于在跨线程访问控件时执行需要在 UI 线程上执行的操作。
在 WinForm 或 WPF 中,当需要在 UI 线程上执行操作时,可以使用 MethodInvoker 来封装需要执行的代码,并通过 Invoke 或 BeginInvoke 方法在 UI 线程上异步或同步执行这段代码。
例如,MethodInvoker 的定义如下:
public delegate void MethodInvoker();
然后可以使用 MethodInvoker 来创建一个委托实例,将需要在 UI 线程上执行的操作包装在这个委托中,然后传递给 Invoke 或 BeginInvoke 方法。这样可以确保操作在 UI 线程上安全地执行,避免产生跨线程访问控件时可能出现的线程安全问题。
总之,MethodInvoker 主要用于创建不带参数且无返回值的委托,用于在跨线程访问控件时执行需要在 UI 线程上执行的操作。
MethodInvoker和Action的区别
Action 和 MethodInvoker 都是委托类型,用于表示可以被调用的方法或代码块。它们之间的区别在于:
参数和返回值:
- Action 是一个泛型委托类型,可以表示不带参数或带有参数但不返回数值的方法或代码块。
- MethodInvoker 是一个特定的委托类型,它表示不带参数且没有返回值的方法或代码块。在实际使用中,通常用于在 UI 线程上执行操作。
使用场景:
- Action 可以用于任何需要表示不带参数或带有参数但不返回数值的方法或代码块的场景,而不限于 UI 编程。
- MethodInvoker 在 UI 编程中比较常见,用于在 UI 线程上执行操作,确保操作在 UI 线程上安全地执行。
因此,如果你需要表示一个不带参数或带有参数但不返回数值的方法或代码块,并且这个方法或代码块不一定涉及 UI 控件的操作,可以选择使用 Action。而如果你需要在 UI 线程上执行特定的操作,通常会选择使用 MethodInvoker 或简化后的 lambda 表达式来确保线程安全性。
个人总结
1.跨线程操作ui控件时如果需要立刻得到结果用Invoke同步方法
如果不需要立刻得到结果可以用BeginInvoke方法
2.用Action委托就好MethodInvoker委托不了解不使用