日期:2014-05-19  浏览次数:20827 次

求助: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;

很土的一个方法-_-#