线程,UI更新可以吗? [英] Thread, UI update is this ok?
问题描述
嗨组,
我一直在读线程并从
工作线程更新ui我做了这个样本但是有效但是我想知道它是否是好的方法吗?我能改进一下吗?什么是
更新我的表单上的多个控件的最佳实践,例如5个标签左右,只需保持
将它们传递给构造函数?
< br $>
Greetz,Peter
在我的表格上:
Private Sub Button1_Click(ByVal sender As System.Object,ByVal e as
System.EventArgs)处理Button1.Click
Dim oMyUpd作为新的MyUpdater(ProgressBar1,lblPct)
oMyUpd.Start()
结束子
''工人线程
进口System.Threading
''======================================== ========= =====================
公共类MyUpdater
代表Sub UpdateStarter()
代表Sub FeedBack(ByVal myValue As Integer)
私有oThread As Thread
私有oMyUpdate作为新的UpdateStarter (AddressOf StartUpdating)
私人计划作为ProgressBar
私人信息标签作为标签
Public Sub New(ByVal myProg As ProgressBar,ByVal myLabel As Label)
progy = myProg
infoLbl = myLabel
结束子
Public Sub [开始]()
oMyUpdate.BeginInvoke(Nothing,Nothing)
End Sub
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
对于i as Integer = 0到15
progy.BeginInvoke(giveFeedBack,New Object(){i})
Thread.Sleep(200)
下一页
结束子
Public Sub IncreaseValue(ByVal myVal As Integer)
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100,2))
End Sub
结束课程
-
今天的编程是软件工程师努力建立更大和更好的白痴的竞赛 - 证明程序,宇宙试图生产
更大更好的白痴。到目前为止,宇宙正在赢得胜利。 (Rich Cook)
文章< uJ ************** @ TK2MSFTNGP02.phx.gbl> ;,
pp*****@nospam.hotmail.com 说......
嗨组,
我一直在读线程并从
更新ui工作线程和我做了这个样本有效,但我想知道它是否是好的方法吗?我能改进一下吗?什么是
更新我的表单上的多个控件的最佳实践,例如5个标签左右,只需保持
将它们传递给构造函数?
< br $>
Greetz,Peter
在我的表格上:
Private Sub Button1_Click(ByVal sender As System.Object,ByVal e as
System.EventArgs)处理Button1.Click
Dim oMyUpd作为新的MyUpdater(ProgressBar1,lblPct)
oMyUpd.Start()
结束子
''工人线程
进口System.Threading
''======================================== ========= =====================
公共类MyUpdater
代表Sub UpdateStarter()
代表Sub FeedBack(ByVal myValue As Integer)
私有oThread As Thread
私有oMyUpdate作为新的UpdateStarter (AddressOf StartUpdating)
私人计划作为ProgressBar
私人信息标签
Public Sub New(ByVal myProg As ProgressBar,ByVal myLabel As Label)
progy = myProg
infoLbl = myLabel
结束子
Public Sub [开始]()
oMyUpdate.BeginInvoke(Nothing,Nothing)
结束子
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
对于i as Integer = 0到15
progy.BeginInvoke(giveFeedBack,New Object(){i})
Thread.Sleep(200)
下一个
我喜欢在本地线程之间保持编组逻辑
$ b正在访问UI的$ b方法。像这样(在VB.NET中没有用
a进行编码,所以我的语法可能有些生疏):
Public Sub IncreaseValue(ByVal myVal As Integer)
如果progy.InvokeRequired那么
progy.Invoke(新反馈(AddressOf IncreaseValue),_
new Object(){ i})
返回
结束如果
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100,2))
end sub
现在你只需要直接调用IncreaseValue
" StartUpdating"方法 - 你不需要多线程的东西在
你的循环代码。
这也有好处,如果你把这个方法移动到用户界面
线程,progy.InvokeRequired将返回false并且您将立即更新
控件 - 无需使用Invoke。虽然拨打Invoke并不是一笔巨大的费用,但为什么在你不需要的时候打电话呢? :)
-
Patrick Steele
http://weblogs.asp.net/psteele
感谢您的解释
Greetz Peter
-
今天的编程是软件工程师之间的竞赛努力建立更大,更好的防止白痴程序,并且宇宙试图生产更大更好的白痴。到目前为止,宇宙正在赢得胜利。 (Rich Cook)
" Patrick Steele" < pa ***** @ mvps.orgschreef in bericht
新闻:MP ************************ @ msnews.microsoft.c om ...
文章< uJ ************** @ TK2MSFTNGP02.phx.gbl> ;,
pp*****@nospam.hotmail.com 说......
嗨组,
我一直在读线程并从
更新ui工作线程和我做了这个样本,但我想知道是否
它是'
可行的方法吗?我能改进一下吗?什么是最佳做法
for
更新我的表单上的多个控件,例如5个标签左右,只需
keep
< blockquote class =post_quotes>
将它们传递给构造函数?
Greetz,Peter
在我的表格上:
Private Sub Button1_Click(ByVal sender As System.Object,ByVal e As
System.EventArgs)处理Button1.Click
Dim oMyUpd作为新的MyUpdater(ProgressBar1,lblPct)
oMyUpd.Start()
End Sub
''The工人线程
进口System.Threading
''================== =============================== =================== ==
公共类MyUpdater
委托子UpdateStarter()
委托子反馈(ByVal myValue作为整数)
私有oThread作为线程
私有oMyUpdate作为新的UpdateStarter(AddressOf StartUpdating)
私人计划作为ProgressBar
私人infoLbl作为标签
Public Sub New(ByVal myProg As ProgressBar,ByVal myLabel As标签)
progy = myProg
infoLbl = myLabel
End Sub
Public Sub [开始]()
oMyUpdate.BeginInvoke(Nothing,Nothing)
End Sub
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
For i As Integer = 0 to 15
prog.BeginInvoke(giveFeedBack,New Object(){i})
Thread.Sleep(200)
下一个
我ike保持在访问UI的
方法本地线程之间的编组逻辑。像这样(在VB.NET中没有用
a进行编码,所以我的语法可能有些生疏):
Public Sub IncreaseValue(ByVal myVal As Integer)
如果progy.InvokeRequired那么
progy.Invoke(新反馈(AddressOf IncreaseValue),_
new Object(){ i})
返回
结束如果
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100,2))
end sub
现在你只需要直接调用IncreaseValue
" StartUpdating"方法 - 你不需要多线程的东西在
你的循环代码。
这也有好处,如果你把这个方法移动到用户界面
线程,progy.InvokeRequired将返回false并且您将立即更新
控件 - 无需使用Invoke。虽然拨打Invoke并不是一笔巨大的费用,但为什么在你不需要的时候打电话呢? :)
-
Patrick Steele
http://weblogs.asp.net/psteele
只是为了确定,这是什么你的意思是?
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
我的整数= 0到15
IncreaseValue(i)
Thread.Sleep(200)
下一页
结束子
Public Sub IncreaseValue(ByVal myVal As Integer)
如果progy.InvokeRequired那么
progy.Invoke(New FeedBack(AddressOf IncreaseValue),New Object()
{myVal})
返回
结束如果
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100,2))< br $>
结束子
Greetz Peter
-
今天编程我这是一场软件工程师之间的竞赛,他们正在努力建立更大,更好的防止白痴程序,并且宇宙试图制造更大更好的白痴。到目前为止,宇宙正在赢得胜利。 (Rich Cook)
" Peter Proost" < pp ***** @ nospam.hotmail.comschreef在bericht
新闻:eE ************** @ TK2MSFTNGP06.phx.gbl ...
感谢您的解释
Greetz Peter
-
今天的编程是软件工程师之间的竞赛,他们正在努力建立更大,更好的防止白痴的程序和宇宙试图产生更大更好的白痴。到目前为止,宇宙正在赢得胜利。 (Rich Cook)
" Patrick Steele" < pa ***** @ mvps.orgschreef in bericht
新闻:MP ************************ @ msnews.microsoft.c om ...
文章< uJ ************** @ TK2MSFTNGP02.phx.gbl> ;,
pp*****@nospam.hotmail.com 说......
嗨组,
>
我一直在读线程并更新ui />
工作线程和我做了这个样本有效,但我想知道
if
它是
可行的方法吗?我能改进一下吗?什么是最佳做法
for
更新我的表单上的多个控件,例如5个标签左右,只需
keep
< blockquote class =post_quotes>
将它们传递给构造函数?
>
格雷茨,彼得
>
在我的表格上:
>
Private Sub Button1_Click(ByVal sender As System.Object,ByVal e As
System.EventArgs)处理Button1.Click
Dim oMyUpd作为新的MyUpdater(ProgressBar1,lblPct)
oMyUpd.Start()
>
结束子
>
''工人线程
>
进口系统。线程
>
>
''======================== $======================== =====================
Public Class MyUpdater
Delegate Sub UpdateStarter()
代表Sub FeedBack(ByVal myValue As Integer)
>
私有oThread为线程
私有oMyUpdate为新UpdateStarter(AddressOf StartUpdating)
>
私人计划作为ProgressBar
私人信息标签
>
Public Sub New(ByVal myProg As ProgressBar,ByVal myLabel As
Label)
progy = myProg
infoLbl = myLabel
End Sub
& gt;
Public Sub [开始]()
oMyUpdate.BeginInvoke(没什么,没什么)
结束子
>
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
对于i as Integer = 0到15
progy.BeginInvoke(giveFeedBack,New Object(){i})
Thread.Sleep(200)
下一个
我喜欢在访问UI的
方法的本地线程之间保持编组的逻辑。像这样(在VB.NET中没有用
a进行编码,所以我的语法可能有些生疏):
Public Sub IncreaseValue(ByVal myVal As Integer)
如果progy.InvokeRequired那么
progy.Invoke(新反馈(AddressOf IncreaseValue),_
new Object(){ i})
返回
结束如果
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100,2))
end sub
现在你只需要直接调用IncreaseValue
" StartUpdating"方法 - 你不需要多线程的东西在
你的循环代码。
这也有好处,如果你把这个方法移动到用户界面
线程,progy.InvokeRequired将返回false并且您将立即更新
控件 - 无需使用Invoke。虽然拨打Invoke并不是一笔巨大的费用,但为什么在你不需要的时候打电话呢? :)
-
Patrick Steele
http://weblogs.asp.net/psteele
Hi group,
I have been doing some reading on threading and updating the ui from a
worker thread and I made this sample which works but I was wondering if it''s
the ok way to do it? Can I improve something? What''s the best practise for
updating multiple controls on my form for example 5 labels or so, just keep
passing them to the constructor?
Greetz, Peter
On my Form:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim oMyUpd As New MyUpdater(ProgressBar1, lblPct)
oMyUpd.Start()
End Sub
''The worker thread
Imports System.Threading
''================================================= =====================
Public Class MyUpdater
Delegate Sub UpdateStarter()
Delegate Sub FeedBack(ByVal myValue As Integer)
Private oThread As Thread
Private oMyUpdate As New UpdateStarter(AddressOf StartUpdating)
Private progy As ProgressBar
Private infoLbl As Label
Public Sub New(ByVal myProg As ProgressBar, ByVal myLabel As Label)
progy = myProg
infoLbl = myLabel
End Sub
Public Sub [Start]()
oMyUpdate.BeginInvoke(Nothing, Nothing)
End Sub
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
For i As Integer = 0 To 15
progy.BeginInvoke(giveFeedBack, New Object() {i})
Thread.Sleep(200)
Next
End Sub
Public Sub IncreaseValue(ByVal myVal As Integer)
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100, 2))
End Sub
End Class
--
Programming today is a race between software engineers striving to build
bigger and better idiot-proof programs, and the Universe trying to produce
bigger and better idiots. So far, the Universe is winning. (Rich Cook)
In article <uJ**************@TK2MSFTNGP02.phx.gbl>,
pp*****@nospam.hotmail.com says...Hi group,
I have been doing some reading on threading and updating the ui from a
worker thread and I made this sample which works but I was wondering if it''s
the ok way to do it? Can I improve something? What''s the best practise for
updating multiple controls on my form for example 5 labels or so, just keep
passing them to the constructor?
Greetz, Peter
On my Form:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim oMyUpd As New MyUpdater(ProgressBar1, lblPct)
oMyUpd.Start()
End Sub
''The worker thread
Imports System.Threading
''================================================= =====================
Public Class MyUpdater
Delegate Sub UpdateStarter()
Delegate Sub FeedBack(ByVal myValue As Integer)
Private oThread As Thread
Private oMyUpdate As New UpdateStarter(AddressOf StartUpdating)
Private progy As ProgressBar
Private infoLbl As Label
Public Sub New(ByVal myProg As ProgressBar, ByVal myLabel As Label)
progy = myProg
infoLbl = myLabel
End Sub
Public Sub [Start]()
oMyUpdate.BeginInvoke(Nothing, Nothing)
End Sub
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
For i As Integer = 0 To 15
progy.BeginInvoke(giveFeedBack, New Object() {i})
Thread.Sleep(200)
NextI like to keep the logic of marshalling between threads local to the
method that is accessing the UI. Like this (haven''t coded in VB.NET in
a while so I might be little rusty on the syntax):
Public Sub IncreaseValue(ByVal myVal As Integer)
If progy.InvokeRequired Then
progy.Invoke(New Feedback(AddressOf IncreaseValue), _
new Object() {i})
return
end if
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100, 2))
end sub
Now you just need to call IncreaseValue directly in your
"StartUpdating" method -- you don''t need the multithreading stuff in
your loop code.
This also has the benefit that if you ever move this method into the UI
thread, the "progy.InvokeRequired" will return false and you''ll update
the control right away -- no need to use Invoke. While it''s not a huge
expense to call Invoke, why call it when you don''t have to? :)
--
Patrick Steele
http://weblogs.asp.net/psteele
Hi,
Thanks for the explanation
Greetz Peter
--
Programming today is a race between software engineers striving to build
bigger and better idiot-proof programs, and the Universe trying to produce
bigger and better idiots. So far, the Universe is winning. (Rich Cook)
"Patrick Steele" <pa*****@mvps.orgschreef in bericht
news:MP************************@msnews.microsoft.c om...In article <uJ**************@TK2MSFTNGP02.phx.gbl>,
pp*****@nospam.hotmail.com says...Hi group,
I have been doing some reading on threading and updating the ui from a
worker thread and I made this sample which works but I was wondering if
it''s
the ok way to do it? Can I improve something? What''s the best practise
for
updating multiple controls on my form for example 5 labels or so, just
keep
passing them to the constructor?
Greetz, Peter
On my Form:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim oMyUpd As New MyUpdater(ProgressBar1, lblPct)
oMyUpd.Start()
End Sub
''The worker thread
Imports System.Threading
''================================================= =====================
Public Class MyUpdater
Delegate Sub UpdateStarter()
Delegate Sub FeedBack(ByVal myValue As Integer)
Private oThread As Thread
Private oMyUpdate As New UpdateStarter(AddressOf StartUpdating)
Private progy As ProgressBar
Private infoLbl As Label
Public Sub New(ByVal myProg As ProgressBar, ByVal myLabel As Label)
progy = myProg
infoLbl = myLabel
End Sub
Public Sub [Start]()
oMyUpdate.BeginInvoke(Nothing, Nothing)
End Sub
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
For i As Integer = 0 To 15
progy.BeginInvoke(giveFeedBack, New Object() {i})
Thread.Sleep(200)
Next
I like to keep the logic of marshalling between threads local to the
method that is accessing the UI. Like this (haven''t coded in VB.NET in
a while so I might be little rusty on the syntax):
Public Sub IncreaseValue(ByVal myVal As Integer)
If progy.InvokeRequired Then
progy.Invoke(New Feedback(AddressOf IncreaseValue), _
new Object() {i})
return
end if
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100, 2))
end sub
Now you just need to call IncreaseValue directly in your
"StartUpdating" method -- you don''t need the multithreading stuff in
your loop code.
This also has the benefit that if you ever move this method into the UI
thread, the "progy.InvokeRequired" will return false and you''ll update
the control right away -- no need to use Invoke. While it''s not a huge
expense to call Invoke, why call it when you don''t have to? :)
--
Patrick Steele
http://weblogs.asp.net/psteele
Just to make sure, is this what you mean?
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
For i As Integer = 0 To 15
IncreaseValue(i)
Thread.Sleep(200)
Next
End Sub
Public Sub IncreaseValue(ByVal myVal As Integer)
If progy.InvokeRequired Then
progy.Invoke(New FeedBack(AddressOf IncreaseValue), New Object()
{myVal})
Return
End If
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100, 2))
End Sub
Greetz Peter
--
Programming today is a race between software engineers striving to build
bigger and better idiot-proof programs, and the Universe trying to produce
bigger and better idiots. So far, the Universe is winning. (Rich Cook)
"Peter Proost" <pp*****@nospam.hotmail.comschreef in bericht
news:eE**************@TK2MSFTNGP06.phx.gbl...Hi,
Thanks for the explanation
Greetz Peter
--
Programming today is a race between software engineers striving to build
bigger and better idiot-proof programs, and the Universe trying to produce
bigger and better idiots. So far, the Universe is winning. (Rich Cook)
"Patrick Steele" <pa*****@mvps.orgschreef in bericht
news:MP************************@msnews.microsoft.c om...In article <uJ**************@TK2MSFTNGP02.phx.gbl>,
pp*****@nospam.hotmail.com says...Hi group,
>
I have been doing some reading on threading and updating the ui from a
worker thread and I made this sample which works but I was wondering
if
it''sthe ok way to do it? Can I improve something? What''s the best practise
for
updating multiple controls on my form for example 5 labels or so, just
keep
passing them to the constructor?
>
Greetz, Peter
>
On my Form:
>
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim oMyUpd As New MyUpdater(ProgressBar1, lblPct)
oMyUpd.Start()
>
End Sub
>
''The worker thread
>
Imports System.Threading
>
>
''================================================= =====================
Public Class MyUpdater
Delegate Sub UpdateStarter()
Delegate Sub FeedBack(ByVal myValue As Integer)
>
Private oThread As Thread
Private oMyUpdate As New UpdateStarter(AddressOf StartUpdating)
>
Private progy As ProgressBar
Private infoLbl As Label
>
Public Sub New(ByVal myProg As ProgressBar, ByVal myLabel As
Label)
progy = myProg
infoLbl = myLabel
End Sub
>
Public Sub [Start]()
oMyUpdate.BeginInvoke(Nothing, Nothing)
End Sub
>
Public Sub StartUpdating()
Dim giveFeedBack As New FeedBack(AddressOf IncreaseValue)
oThread = Thread.CurrentThread
For i As Integer = 0 To 15
progy.BeginInvoke(giveFeedBack, New Object() {i})
Thread.Sleep(200)
NextI like to keep the logic of marshalling between threads local to the
method that is accessing the UI. Like this (haven''t coded in VB.NET in
a while so I might be little rusty on the syntax):
Public Sub IncreaseValue(ByVal myVal As Integer)
If progy.InvokeRequired Then
progy.Invoke(New Feedback(AddressOf IncreaseValue), _
new Object() {i})
return
end if
progy.Value = myVal
infoLbl.Text = CStr(Math.Round(myVal / progy.Maximum * 100, 2))
end sub
Now you just need to call IncreaseValue directly in your
"StartUpdating" method -- you don''t need the multithreading stuff in
your loop code.
This also has the benefit that if you ever move this method into the UI
thread, the "progy.InvokeRequired" will return false and you''ll update
the control right away -- no need to use Invoke. While it''s not a huge
expense to call Invoke, why call it when you don''t have to? :)
--
Patrick Steele
http://weblogs.asp.net/psteele
这篇关于线程,UI更新可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!