求助:WinForm的问题
请问:
在WinForm的一个线程中创建的窗体和控件如何在另一个线程中访问?
正常情况下,这种设置方式会导致异常产生.
谢谢大家了!
------解决方案--------------------多线程不能同时访问一个资源
------解决方案--------------------Invoke?
------解决方案--------------------估计你是VS2005,VS2003是没有这种问题的
VS2005首先要启动一个线程,我用VB.Net为例解释所谓的安全线程,原理是一样的
1、启动线程——声明对应的方法
MyThread = New Threading.Thread(AddressOf ThreadProcSafe)
2、方法中调用修改文本的方法,也是为了安全,两个方法没有合并为一个
Private Sub ThreadProcSafe()
'安全调用线程
Dim II As Integer
For II = 1 To 100000
Thread.Sleep(1000)
'LblTime.Text = II & "秒 "
Me.SetText(II & "秒 ")
Next
End Sub
3、进行安全的更改文本信息,实际上就是多了一步Me.LblTime.InvokeRequired ,判断你处理的控件是否Ok
Private Sub SetText(ByVal [text] As String)
If Me.LblTime.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
Me.Invoke(d, New Object() {[text]})
Else
Me.LblTime.Text = [text]
End If
End Sub
InvokeRequired获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。
实际上也并不复杂——就是多出来一步判断而已。
我不大会C#的写法,大体是应该这样吧,呵呵~~
private void SetText(string text)
{
if (this.LblTime.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] {text});
}
else
{
this.LblTime.Text = text;
}
}
------解决方案--------------------忘记一样,需要前面声明一个委托,呵呵~~
Delegate Sub SetTextCallback(ByVal [text] As String)
------解决方案--------------------定上一个全局变量Tmp,在线程里更改这个值
然后放一个Timer
lbTime.Text = Tmp;
很土的一个方法-_-#