线程,UI更新可以吗? [英] Thread, UI update is this ok?

查看:72
本文介绍了线程,UI更新可以吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨组,


我一直在读线程并从

工作线程更新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)
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


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''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




这篇关于线程,UI更新可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆