c#线程问题:线程间操作无效:从不是创建控件 的线程访问它InvalidOperationException异常
c#线程问题:线程间操作无效:从不是创建控件 的线程访问它InvalidOperationException异常
2008年07月16日 星期三 15:09
摘自http://hi.baidu.com/zzticzh/blog/item/ee4e89020a89a6094bfb518e.html
在有些情况下,您可能需要通过线程调用控件的方法。例如,您可能要在窗体上调用一个禁用按钮或更新显示的方法来响应某个线程执行的操作。.NET Framework 提供从任何线程都可安全调用的方法,以调用与其他线程所拥有的控件进行交互的方法。Invoke 方法允许同步执行控件上的方法,而 BeginInvoke 方法则初始化异步执行。要使用这些方法,必须用与将调用的方法相同的签名声明委托。然后,您可以通过向要调用的方法提供适当的委托来调用窗体上任何控件的 Invoke 或 BeginInvoke 方法。任何必需的参数都包装在 Object 中,并被传输到该方法。
调用涉及其他线程所拥有的控件的方法
用与要调用的方法相同的签名声明一个委托。
下面的示例显示如何使用 Integer 和 String 参数声明委托。
调用涉及其他线程所拥有的控件的方法
用与要调用的方法相同的签名声明一个委托。
下面的示例显示如何使用 Integer 和 String 参数声明委托。
>Visual Basic
Public Delegate Sub myDelegate(ByVal anInteger as Integer, ByVal _
aString as String)
>C#
public delegate void myDelegate(int anInteger, string aString);
使用任何控件来调用对其他线程所拥有的控件进行操作的方法。
注意:
方法所需的参数(如果有)可在 Object 中提供。
如果要同步调用方法,请调用 Control.Invoke 方法。
>Visual Basic
Label1.Invoke(New myDelegate(AddressOf myMethod), New _
Object() {1, "This is the string"})
>C#
Label1.Invoke(new myDelegate(myMethod), new Object[] {1,
"This is the string"});
如果要异步调用方法,请调用 Control.BeginInvoke 方法。
>Visual Basic
Label1.BeginInvoke(New myDelegate(AddressOf myMethod), _
New Object() {1, "This is the string"})
>C#
Label1.BeginInvoke(new myDelegate(myMethod), new
Object[] {1, "This is the string"});
-----------------------------
举个例子:新建一个Windows应用程序项目Win1,在窗体Form1中添加一个Button名称为button1,然后转入代码页,按下面修改代码
using System;
using System.Windows.Forms;
namespace win1
{
public partial class Form1 : Form
{
public delegate void 我的委托();//声明一个委托
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)//此处先双击button1以便产生代码并且自动创建事件委托
{
new System.Threading.Thread(new System.Threading.ThreadStart (新线程)).Start();//创建一个新的线程并启动
}
public void 设置文字()
{
button1.Text = "Hello";
}
public void 新线程()
{
System.Threading.Thread.Sleep(2000);//线程休眠2秒
button1.BeginInvoke(new 我的委托(设置文字));//在button1所在线程上执行“设置文字”
}
}
}
运行:单击button1,两秒之后文字发生变化
2008年07月16日 星期三 15:09
摘自http://hi.baidu.com/zzticzh/blog/item/ee4e89020a89a6094bfb518e.html
在有些情况下,您可能需要通过线程调用控件的方法。例如,您可能要在窗体上调用一个禁用按钮或更新显示的方法来响应某个线程执行的操作。.NET Framework 提供从任何线程都可安全调用的方法,以调用与其他线程所拥有的控件进行交互的方法。Invoke 方法允许同步执行控件上的方法,而 BeginInvoke 方法则初始化异步执行。要使用这些方法,必须用与将调用的方法相同的签名声明委托。然后,您可以通过向要调用的方法提供适当的委托来调用窗体上任何控件的 Invoke 或 BeginInvoke 方法。任何必需的参数都包装在 Object 中,并被传输到该方法。
调用涉及其他线程所拥有的控件的方法
用与要调用的方法相同的签名声明一个委托。
下面的示例显示如何使用 Integer 和 String 参数声明委托。
调用涉及其他线程所拥有的控件的方法
用与要调用的方法相同的签名声明一个委托。
下面的示例显示如何使用 Integer 和 String 参数声明委托。
>Visual Basic
Public Delegate Sub myDelegate(ByVal anInteger as Integer, ByVal _
aString as String)
>C#
public delegate void myDelegate(int anInteger, string aString);
使用任何控件来调用对其他线程所拥有的控件进行操作的方法。
注意:
方法所需的参数(如果有)可在 Object 中提供。
如果要同步调用方法,请调用 Control.Invoke 方法。
>Visual Basic
Label1.Invoke(New myDelegate(AddressOf myMethod), New _
Object() {1, "This is the string"})
>C#
Label1.Invoke(new myDelegate(myMethod), new Object[] {1,
"This is the string"});
如果要异步调用方法,请调用 Control.BeginInvoke 方法。
>Visual Basic
Label1.BeginInvoke(New myDelegate(AddressOf myMethod), _
New Object() {1, "This is the string"})
>C#
Label1.BeginInvoke(new myDelegate(myMethod), new
Object[] {1, "This is the string"});
-----------------------------
举个例子:新建一个Windows应用程序项目Win1,在窗体Form1中添加一个Button名称为button1,然后转入代码页,按下面修改代码
using System;
using System.Windows.Forms;
namespace win1
{
public partial class Form1 : Form
{
public delegate void 我的委托();//声明一个委托
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)//此处先双击button1以便产生代码并且自动创建事件委托
{
new System.Threading.Thread(new System.Threading.ThreadStart (新线程)).Start();//创建一个新的线程并启动
}
public void 设置文字()
{
button1.Text = "Hello";
}
public void 新线程()
{
System.Threading.Thread.Sleep(2000);//线程休眠2秒
button1.BeginInvoke(new 我的委托(设置文字));//在button1所在线程上执行“设置文字”
}
}
}
运行:单击button1,两秒之后文字发生变化