|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Multithread Revistedupdate when a long database process runs. The database process runs on a separate thread: Dim t As New Thread(AddressOf SomeDatabaseProcess) t.Start() The database process will be called about 10 times in one long routine, starting a new thread each time. But the problem is that I need the thread to finish before code execution continues. The main reason this does not just run on the same thread is that I need to get the darn status bar updated, but the UI freezes up. I tried using t.Join() which does wait for the thread to finish, but it does not allow the UI to be freed up. And I tried setting a global variable to detect when the thread is done, but the code after the thread just runs in a Do Loop until the variable is set, which also freezes up the UI. Any ideas of how to get this working? Derek Hello Derek,
The reason the UI becomes unresponsive is that the long database operations block the message pump. Instead of spinning off new threads, which are unneeded, just massage the message pump immediately after updating the status bar. (See MSDN documentation for application.DoEvents) -Boo Show quoteHide quote > On the main thread I have a status bar in a Windows form that I want > to update when a long database process runs. The database process > runs on a separate thread: > > Dim t As New Thread(AddressOf SomeDatabaseProcess) > > t.Start() > > The database process will be called about 10 times in one long > routine, starting a new thread each time. But the problem is that I > need the thread to finish before code execution continues. The main > reason this does not just run on the same thread is that I need to get > the darn status bar updated, but the UI freezes up. I tried using > t.Join() which does wait for the thread to finish, but it does not > allow the UI to be freed up. And I tried setting a global variable to > detect when the thread is done, but the code after the thread just > runs in a Do Loop until the variable is set, which also freezes up the > UI. Any ideas of how to get this working? > > Derek > if you want a responsive UI , one that is capable of terminating a hughe
update for instance , and the ability to perform simultanious tasks like updating a progressbar that gives reall info , and a UI that repainst itself after moving the form etc etc well then you can only acomplish this with multithreading The dissadvantage of using asynchronous code is that it is usualy slower as synchronous code , however how slow is it when the user terminates the program because he believes it doesn`t run at all because it is unresponsive application.doevents is overdone in almost all situations you could better call a refresh on the control regards Michel Posseth [MCP] Show quoteHide quote "GhostInAK" wrote: > Hello Derek, > > The reason the UI becomes unresponsive is that the long database operations > block the message pump. Instead of spinning off new threads, which are unneeded, > just massage the message pump immediately after updating the status bar. > (See MSDN documentation for application.DoEvents) > > -Boo > > > On the main thread I have a status bar in a Windows form that I want > > to update when a long database process runs. The database process > > runs on a separate thread: > > > > Dim t As New Thread(AddressOf SomeDatabaseProcess) > > > > t.Start() > > > > The database process will be called about 10 times in one long > > routine, starting a new thread each time. But the problem is that I > > need the thread to finish before code execution continues. The main > > reason this does not just run on the same thread is that I need to get > > the darn status bar updated, but the UI freezes up. I tried using > > t.Join() which does wait for the thread to finish, but it does not > > allow the UI to be freed up. And I tried setting a global variable to > > detect when the thread is done, but the code after the thread just > > runs in a Do Loop until the variable is set, which also freezes up the > > UI. Any ideas of how to get this working? > > > > Derek > > > > > Michel
> application.doevents is overdone in almost all situations you could better But you see than in my idea in the by the OPr explained sample only the > call a refresh on the control > control, which is AFAIK done by the progressbar itself. :-) CorShow quoteHide quote "M. Posseth" <MPoss***@discussions.microsoft.com> schreef in bericht news:AC028C0F-86D9-4656-A5F3-2D031F229DFE@microsoft.com... > > if you want a responsive UI , one that is capable of terminating a hughe > update for instance , and the ability to perform simultanious tasks like > updating a progressbar that gives reall info , and a UI that repainst > itself > after moving the form etc etc well then you can only acomplish this with > multithreading > > The dissadvantage of using asynchronous code is that it is usualy slower > as > synchronous code , however how slow is it when the user terminates the > program because he believes it doesn`t run at all because it is > unresponsive > > application.doevents is overdone in almost all situations you could better > call a refresh on the control > > > regards > > Michel Posseth [MCP] > > > "GhostInAK" wrote: > >> Hello Derek, >> >> The reason the UI becomes unresponsive is that the long database >> operations >> block the message pump. Instead of spinning off new threads, which are >> unneeded, >> just massage the message pump immediately after updating the status bar. >> (See MSDN documentation for application.DoEvents) >> >> -Boo >> >> > On the main thread I have a status bar in a Windows form that I want >> > to update when a long database process runs. The database process >> > runs on a separate thread: >> > >> > Dim t As New Thread(AddressOf SomeDatabaseProcess) >> > >> > t.Start() >> > >> > The database process will be called about 10 times in one long >> > routine, starting a new thread each time. But the problem is that I >> > need the thread to finish before code execution continues. The main >> > reason this does not just run on the same thread is that I need to get >> > the darn status bar updated, but the UI freezes up. I tried using >> > t.Join() which does wait for the thread to finish, but it does not >> > allow the UI to be freed up. And I tried setting a global variable to >> > detect when the thread is done, but the code after the thread just >> > runs in a Do Loop until the variable is set, which also freezes up the >> > UI. Any ideas of how to get this working? >> > >> > Derek >> > >> >> >> Not it shouldn`t be necesary ,
i wrote a nice demo for the TS and for the sceptic people :-) take a form throw 2 buttons on it and a progressbar call the progressbar pbmain now copy paste this : Imports System.Threading Public Class Form1 Private Mvar_Cancell As Boolean Friend Property Cancell() As Boolean Get Return Mvar_Cancell End Get Set(ByVal value As Boolean) Mvar_Cancell = value Me.Button1.Enabled = value End Set End Property Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Me.Cancell = False With pbMain .Value = 0 .Maximum = 100 .Minimum = 0 End With Dim AsyncProcess As New AsynchMethodInvoker(AddressOf Me.pbLoop) AsyncProcess.BeginInvoke(Nothing, Nothing) AsyncProcess = New AsynchMethodInvoker(AddressOf Me.DoSomething) AsyncProcess.BeginInvoke(Nothing, Nothing) End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Cancell = True End Sub Private Sub DoSomething() Do While Not Me.Cancell Debug.WriteLine("hello world") Loop End Sub Delegate Sub CrossThreadInvParaMB(ByVal val As Integer) Private Sub pbLoop() Dim i As Integer Do While Not Me.Cancell Thread.Sleep(50) i += 1 If i = 101 Then i = 0 SetPbValue(i) Loop i = 100 SetPbValue(i) End Sub Delegate Sub AsynchMethodInvoker() Public Sub SetPbValue(ByVal Count As Integer) If Me.pbMain.InvokeRequired Then Dim d As New CrossThreadInvParaMB(AddressOf SetPbValue) Try Me.Invoke(d, New Object() {Count}) Catch ex As Exception End Try Else Me.pbMain.Value = Count End If End Sub Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing Me.Cancell = True End Sub End Class i hope this gives you all an idea in what i mean ,,, the method that is now updating the progressbar runs in a seperate thread to make it even nicer i run another worker thread wich prints hello world statements to the debug window these threads can comunicate to the progressbar through the SetPbValue method i hope this gives the TS some new input to solve his problem Show quoteHide quote "Cor Ligthert [MVP]" wrote: > Michel > > > application.doevents is overdone in almost all situations you could better > > call a refresh on the control > > > But you see than in my idea in the by the OPr explained sample only the > control, which is AFAIK done by the progressbar itself. > > :-) > > Cor > > "M. Posseth" <MPoss***@discussions.microsoft.com> schreef in bericht > news:AC028C0F-86D9-4656-A5F3-2D031F229DFE@microsoft.com... > > > > if you want a responsive UI , one that is capable of terminating a hughe > > update for instance , and the ability to perform simultanious tasks like > > updating a progressbar that gives reall info , and a UI that repainst > > itself > > after moving the form etc etc well then you can only acomplish this with > > multithreading > > > > The dissadvantage of using asynchronous code is that it is usualy slower > > as > > synchronous code , however how slow is it when the user terminates the > > program because he believes it doesn`t run at all because it is > > unresponsive > > > > application.doevents is overdone in almost all situations you could better > > call a refresh on the control > > > > > > regards > > > > Michel Posseth [MCP] > > > > > > "GhostInAK" wrote: > > > >> Hello Derek, > >> > >> The reason the UI becomes unresponsive is that the long database > >> operations > >> block the message pump. Instead of spinning off new threads, which are > >> unneeded, > >> just massage the message pump immediately after updating the status bar. > >> (See MSDN documentation for application.DoEvents) > >> > >> -Boo > >> > >> > On the main thread I have a status bar in a Windows form that I want > >> > to update when a long database process runs. The database process > >> > runs on a separate thread: > >> > > >> > Dim t As New Thread(AddressOf SomeDatabaseProcess) > >> > > >> > t.Start() > >> > > >> > The database process will be called about 10 times in one long > >> > routine, starting a new thread each time. But the problem is that I > >> > need the thread to finish before code execution continues. The main > >> > reason this does not just run on the same thread is that I need to get > >> > the darn status bar updated, but the UI freezes up. I tried using > >> > t.Join() which does wait for the thread to finish, but it does not > >> > allow the UI to be freed up. And I tried setting a global variable to > >> > detect when the thread is done, but the code after the thread just > >> > runs in a Do Loop until the variable is set, which also freezes up the > >> > UI. Any ideas of how to get this working? > >> > > >> > Derek > >> > > >> > >> > >> > > > My dear Michel,
I only did mean that >>application.doevents is overdone in almost all situations you could better call a refresh on the control I see that nowhere in your code.If that is done to refresh and the form as it is hidden by another program, than it will not help, so it is neither a solution. :-) CorShow quoteHide quote "M. Posseth" <MPoss***@discussions.microsoft.com> schreef in bericht news:994565FB-6525-4021-B2C9-59BB93978E6C@microsoft.com... > Not it shouldn`t be necesary , > > i wrote a nice demo for the TS and for the sceptic people :-) > > take a form throw 2 buttons on it and a progressbar > > call the progressbar pbmain > > > now copy paste this : > > Imports System.Threading > Public Class Form1 > Private Mvar_Cancell As Boolean > Friend Property Cancell() As Boolean > Get > Return Mvar_Cancell > End Get > Set(ByVal value As Boolean) > Mvar_Cancell = value > Me.Button1.Enabled = value > End Set > End Property > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles Button1.Click > Me.Cancell = False > With pbMain > .Value = 0 > .Maximum = 100 > .Minimum = 0 > End With > > Dim AsyncProcess As New AsynchMethodInvoker(AddressOf Me.pbLoop) > AsyncProcess.BeginInvoke(Nothing, Nothing) > > AsyncProcess = New AsynchMethodInvoker(AddressOf Me.DoSomething) > AsyncProcess.BeginInvoke(Nothing, Nothing) > > End Sub > Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles Button2.Click > Cancell = True > End Sub > > Private Sub DoSomething() > Do While Not Me.Cancell > Debug.WriteLine("hello world") > Loop > End Sub > Delegate Sub CrossThreadInvParaMB(ByVal val As Integer) > Private Sub pbLoop() > Dim i As Integer > Do While Not Me.Cancell > Thread.Sleep(50) > i += 1 > If i = 101 Then i = 0 > SetPbValue(i) > Loop > i = 100 > SetPbValue(i) > End Sub > Delegate Sub AsynchMethodInvoker() > Public Sub SetPbValue(ByVal Count As Integer) > If Me.pbMain.InvokeRequired Then > Dim d As New CrossThreadInvParaMB(AddressOf SetPbValue) > Try > Me.Invoke(d, New Object() {Count}) > Catch ex As Exception > > End Try > Else > Me.pbMain.Value = Count > End If > End Sub > Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As > System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing > Me.Cancell = True > End Sub > End Class > > > i hope this gives you all an idea in what i mean ,,, the method that is now > updating the progressbar runs in a seperate thread to make it even nicer i > run another worker thread wich prints hello world statements to the debug > window > > these threads can comunicate to the progressbar through the SetPbValue method > > > i hope this gives the TS some new input to solve his problem > > > > > > > > > "Cor Ligthert [MVP]" wrote: > >> Michel >> >> > application.doevents is overdone in almost all situations you could better >> > call a refresh on the control >> > >> But you see than in my idea in the by the OPr explained sample only the >> control, which is AFAIK done by the progressbar itself. >> >> :-) >> >> Cor >> >> "M. Posseth" <MPoss***@discussions.microsoft.com> schreef in bericht >> news:AC028C0F-86D9-4656-A5F3-2D031F229DFE@microsoft.com... >> > >> > if you want a responsive UI , one that is capable of terminating a hughe >> > update for instance , and the ability to perform simultanious tasks like >> > updating a progressbar that gives reall info , and a UI that repainst >> > itself >> > after moving the form etc etc well then you can only acomplish this with >> > multithreading >> > >> > The dissadvantage of using asynchronous code is that it is usualy slower >> > as >> > synchronous code , however how slow is it when the user terminates the >> > program because he believes it doesn`t run at all because it is >> > unresponsive >> > >> > application.doevents is overdone in almost all situations you could better >> > call a refresh on the control >> > >> > >> > regards >> > >> > Michel Posseth [MCP] >> > >> > >> > "GhostInAK" wrote: >> > >> >> Hello Derek, >> >> >> >> The reason the UI becomes unresponsive is that the long database >> >> operations >> >> block the message pump. Instead of spinning off new threads, which are >> >> unneeded, >> >> just massage the message pump immediately after updating the status bar. >> >> (See MSDN documentation for application.DoEvents) >> >> >> >> -Boo >> >> >> >> > On the main thread I have a status bar in a Windows form that I want >> >> > to update when a long database process runs. The database process >> >> > runs on a separate thread: >> >> > >> >> > Dim t As New Thread(AddressOf SomeDatabaseProcess) >> >> > >> >> > t.Start() >> >> > >> >> > The database process will be called about 10 times in one long >> >> > routine, starting a new thread each time. But the problem is that I >> >> > need the thread to finish before code execution continues. The main >> >> > reason this does not just run on the same thread is that I need to get >> >> > the darn status bar updated, but the UI freezes up. I tried using >> >> > t.Join() which does wait for the thread to finish, but it does not >> >> > allow the UI to be freed up. And I tried setting a global variable to >> >> > detect when the thread is done, but the code after the thread just >> >> > runs in a Do Loop until the variable is set, which also freezes up the >> >> > UI. Any ideas of how to get this working? >> >> > >> >> > Derek >> >> > >> >> >> >> >> >> >> >> >> Hi Cor ,,,
Sorry i was in a bit of a hurry ( on the job when i wrote the previous ) >>> Not it shouldn`t be necesary , should have been>>> No it shouldn`t be necesary , in wich i mend to call the refresh of the control as it should take care of that itself as i showed in my example code ( did you tried it ) this code performs 2 loops in 2 seperate methods that should normally block a ui if it wasn`t written with asynchronous delegates ( even better there is no way you can run these 2 synchronous in the same time ) but even with the hello world loop in synchronous modus you càn not get the ui to respond ,,, my example code shows a responsive ui with a updating progressbar without doevents or a refresh call as assiging the new value will take care of that as the ui is in a responsive modus so this also proves your statement ( that it should not be necesary to call the refresh method of the control ) regards Michel "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> schreef in bericht My dear Michel,news:%23EdZQWEoGHA.1236@TK2MSFTNGP03.phx.gbl... I only did mean that >>application.doevents is overdone in almost all situations you could better I see that nowhere in your code.>>call a refresh on the control If that is done to refresh and the form as it is hidden by another program, than it will not help, so it is neither a solution. :-) CorShow quoteHide quote "M. Posseth" <MPoss***@discussions.microsoft.com> schreef in bericht news:994565FB-6525-4021-B2C9-59BB93978E6C@microsoft.com... > Not it shouldn`t be necesary , > > i wrote a nice demo for the TS and for the sceptic people :-) > > take a form throw 2 buttons on it and a progressbar > > call the progressbar pbmain > > > now copy paste this : > > Imports System.Threading > Public Class Form1 > Private Mvar_Cancell As Boolean > Friend Property Cancell() As Boolean > Get > Return Mvar_Cancell > End Get > Set(ByVal value As Boolean) > Mvar_Cancell = value > Me.Button1.Enabled = value > End Set > End Property > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles Button1.Click > Me.Cancell = False > With pbMain > .Value = 0 > .Maximum = 100 > .Minimum = 0 > End With > > Dim AsyncProcess As New AsynchMethodInvoker(AddressOf Me.pbLoop) > AsyncProcess.BeginInvoke(Nothing, Nothing) > > AsyncProcess = New AsynchMethodInvoker(AddressOf Me.DoSomething) > AsyncProcess.BeginInvoke(Nothing, Nothing) > > End Sub > Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles Button2.Click > Cancell = True > End Sub > > Private Sub DoSomething() > Do While Not Me.Cancell > Debug.WriteLine("hello world") > Loop > End Sub > Delegate Sub CrossThreadInvParaMB(ByVal val As Integer) > Private Sub pbLoop() > Dim i As Integer > Do While Not Me.Cancell > Thread.Sleep(50) > i += 1 > If i = 101 Then i = 0 > SetPbValue(i) > Loop > i = 100 > SetPbValue(i) > End Sub > Delegate Sub AsynchMethodInvoker() > Public Sub SetPbValue(ByVal Count As Integer) > If Me.pbMain.InvokeRequired Then > Dim d As New CrossThreadInvParaMB(AddressOf SetPbValue) > Try > Me.Invoke(d, New Object() {Count}) > Catch ex As Exception > > End Try > Else > Me.pbMain.Value = Count > End If > End Sub > Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As > System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing > Me.Cancell = True > End Sub > End Class > > > i hope this gives you all an idea in what i mean ,,, the method that is > now > updating the progressbar runs in a seperate thread to make it even nicer i > run another worker thread wich prints hello world statements to the debug > window > > these threads can comunicate to the progressbar through the SetPbValue > method > > > i hope this gives the TS some new input to solve his problem > > > > > > > > > "Cor Ligthert [MVP]" wrote: > >> Michel >> >> > application.doevents is overdone in almost all situations you could >> > better >> > call a refresh on the control >> > >> But you see than in my idea in the by the OPr explained sample only the >> control, which is AFAIK done by the progressbar itself. >> >> :-) >> >> Cor >> >> "M. Posseth" <MPoss***@discussions.microsoft.com> schreef in bericht >> news:AC028C0F-86D9-4656-A5F3-2D031F229DFE@microsoft.com... >> > >> > if you want a responsive UI , one that is capable of terminating a >> > hughe >> > update for instance , and the ability to perform simultanious tasks >> > like >> > updating a progressbar that gives reall info , and a UI that repainst >> > itself >> > after moving the form etc etc well then you can only acomplish this >> > with >> > multithreading >> > >> > The dissadvantage of using asynchronous code is that it is usualy >> > slower >> > as >> > synchronous code , however how slow is it when the user terminates the >> > program because he believes it doesn`t run at all because it is >> > unresponsive >> > >> > application.doevents is overdone in almost all situations you could >> > better >> > call a refresh on the control >> > >> > >> > regards >> > >> > Michel Posseth [MCP] >> > >> > >> > "GhostInAK" wrote: >> > >> >> Hello Derek, >> >> >> >> The reason the UI becomes unresponsive is that the long database >> >> operations >> >> block the message pump. Instead of spinning off new threads, which >> >> are >> >> unneeded, >> >> just massage the message pump immediately after updating the status >> >> bar. >> >> (See MSDN documentation for application.DoEvents) >> >> >> >> -Boo >> >> >> >> > On the main thread I have a status bar in a Windows form that I want >> >> > to update when a long database process runs. The database process >> >> > runs on a separate thread: >> >> > >> >> > Dim t As New Thread(AddressOf SomeDatabaseProcess) >> >> > >> >> > t.Start() >> >> > >> >> > The database process will be called about 10 times in one long >> >> > routine, starting a new thread each time. But the problem is that I >> >> > need the thread to finish before code execution continues. The main >> >> > reason this does not just run on the same thread is that I need to >> >> > get >> >> > the darn status bar updated, but the UI freezes up. I tried using >> >> > t.Join() which does wait for the thread to finish, but it does not >> >> > allow the UI to be freed up. And I tried setting a global variable >> >> > to >> >> > detect when the thread is done, but the code after the thread just >> >> > runs in a Do Loop until the variable is set, which also freezes up >> >> > the >> >> > UI. Any ideas of how to get this working? >> >> > >> >> > Derek >> >> > >> >> >> >> >> >> >> >> >> Michel,
I have not any doubt if you made it and shows it that it works, and even if it does not work that it is a typo. :-) CorShow quoteHide quote "Michel Posseth [MCP]" <M***@posseth.com> schreef in bericht news:%23wvyoLFoGHA.4636@TK2MSFTNGP03.phx.gbl... > > Hi Cor ,,, > > Sorry i was in a bit of a hurry ( on the job when i wrote the previous ) > >>>> Not it shouldn`t be necesary , > should have been > >>>> No it shouldn`t be necesary , > > in wich i mend to call the refresh of the control as it should take care > of that itself > as i showed in my example code ( did you tried it ) > > this code performs 2 loops in 2 seperate methods that should normally > block a ui if it wasn`t written with asynchronous delegates > ( even better there is no way you can run these 2 synchronous in the same > time ) but even with the hello world loop in synchronous modus > you càn not get the ui to respond ,,, my example code shows a responsive > ui with a updating progressbar without doevents or a refresh call > > as assiging the new value will take care of that as the ui is in a > responsive modus > > so this also proves your statement ( that it should not be necesary to > call the refresh method of the control ) > > > regards > > Michel > > > > > > > > > > "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> schreef in bericht > news:%23EdZQWEoGHA.1236@TK2MSFTNGP03.phx.gbl... > My dear Michel, > > I only did mean that > >>>application.doevents is overdone in almost all situations you could >>>better call a refresh on the control > > I see that nowhere in your code. > > If that is done to refresh and the form as it is hidden by another > program, than it will not help, so it is neither a solution. > > :-) > > Cor > > > > "M. Posseth" <MPoss***@discussions.microsoft.com> schreef in bericht > news:994565FB-6525-4021-B2C9-59BB93978E6C@microsoft.com... >> Not it shouldn`t be necesary , >> >> i wrote a nice demo for the TS and for the sceptic people :-) >> >> take a form throw 2 buttons on it and a progressbar >> >> call the progressbar pbmain >> >> >> now copy paste this : >> >> Imports System.Threading >> Public Class Form1 >> Private Mvar_Cancell As Boolean >> Friend Property Cancell() As Boolean >> Get >> Return Mvar_Cancell >> End Get >> Set(ByVal value As Boolean) >> Mvar_Cancell = value >> Me.Button1.Enabled = value >> End Set >> End Property >> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As >> System.EventArgs) Handles Button1.Click >> Me.Cancell = False >> With pbMain >> .Value = 0 >> .Maximum = 100 >> .Minimum = 0 >> End With >> >> Dim AsyncProcess As New AsynchMethodInvoker(AddressOf Me.pbLoop) >> AsyncProcess.BeginInvoke(Nothing, Nothing) >> >> AsyncProcess = New AsynchMethodInvoker(AddressOf Me.DoSomething) >> AsyncProcess.BeginInvoke(Nothing, Nothing) >> >> End Sub >> Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As >> System.EventArgs) Handles Button2.Click >> Cancell = True >> End Sub >> >> Private Sub DoSomething() >> Do While Not Me.Cancell >> Debug.WriteLine("hello world") >> Loop >> End Sub >> Delegate Sub CrossThreadInvParaMB(ByVal val As Integer) >> Private Sub pbLoop() >> Dim i As Integer >> Do While Not Me.Cancell >> Thread.Sleep(50) >> i += 1 >> If i = 101 Then i = 0 >> SetPbValue(i) >> Loop >> i = 100 >> SetPbValue(i) >> End Sub >> Delegate Sub AsynchMethodInvoker() >> Public Sub SetPbValue(ByVal Count As Integer) >> If Me.pbMain.InvokeRequired Then >> Dim d As New CrossThreadInvParaMB(AddressOf SetPbValue) >> Try >> Me.Invoke(d, New Object() {Count}) >> Catch ex As Exception >> >> End Try >> Else >> Me.pbMain.Value = Count >> End If >> End Sub >> Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As >> System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing >> Me.Cancell = True >> End Sub >> End Class >> >> >> i hope this gives you all an idea in what i mean ,,, the method that is >> now >> updating the progressbar runs in a seperate thread to make it even nicer >> i >> run another worker thread wich prints hello world statements to the debug >> window >> >> these threads can comunicate to the progressbar through the SetPbValue >> method >> >> >> i hope this gives the TS some new input to solve his problem >> >> >> >> >> >> >> >> >> "Cor Ligthert [MVP]" wrote: >> >>> Michel >>> >>> > application.doevents is overdone in almost all situations you could >>> > better >>> > call a refresh on the control >>> > >>> But you see than in my idea in the by the OPr explained sample only the >>> control, which is AFAIK done by the progressbar itself. >>> >>> :-) >>> >>> Cor >>> >>> "M. Posseth" <MPoss***@discussions.microsoft.com> schreef in bericht >>> news:AC028C0F-86D9-4656-A5F3-2D031F229DFE@microsoft.com... >>> > >>> > if you want a responsive UI , one that is capable of terminating a >>> > hughe >>> > update for instance , and the ability to perform simultanious tasks >>> > like >>> > updating a progressbar that gives reall info , and a UI that repainst >>> > itself >>> > after moving the form etc etc well then you can only acomplish this >>> > with >>> > multithreading >>> > >>> > The dissadvantage of using asynchronous code is that it is usualy >>> > slower >>> > as >>> > synchronous code , however how slow is it when the user terminates the >>> > program because he believes it doesn`t run at all because it is >>> > unresponsive >>> > >>> > application.doevents is overdone in almost all situations you could >>> > better >>> > call a refresh on the control >>> > >>> > >>> > regards >>> > >>> > Michel Posseth [MCP] >>> > >>> > >>> > "GhostInAK" wrote: >>> > >>> >> Hello Derek, >>> >> >>> >> The reason the UI becomes unresponsive is that the long database >>> >> operations >>> >> block the message pump. Instead of spinning off new threads, which >>> >> are >>> >> unneeded, >>> >> just massage the message pump immediately after updating the status >>> >> bar. >>> >> (See MSDN documentation for application.DoEvents) >>> >> >>> >> -Boo >>> >> >>> >> > On the main thread I have a status bar in a Windows form that I >>> >> > want >>> >> > to update when a long database process runs. The database process >>> >> > runs on a separate thread: >>> >> > >>> >> > Dim t As New Thread(AddressOf SomeDatabaseProcess) >>> >> > >>> >> > t.Start() >>> >> > >>> >> > The database process will be called about 10 times in one long >>> >> > routine, starting a new thread each time. But the problem is that >>> >> > I >>> >> > need the thread to finish before code execution continues. The >>> >> > main >>> >> > reason this does not just run on the same thread is that I need to >>> >> > get >>> >> > the darn status bar updated, but the UI freezes up. I tried using >>> >> > t.Join() which does wait for the thread to finish, but it does not >>> >> > allow the UI to be freed up. And I tried setting a global variable >>> >> > to >>> >> > detect when the thread is done, but the code after the thread just >>> >> > runs in a Do Loop until the variable is set, which also freezes up >>> >> > the >>> >> > UI. Any ideas of how to get this working? >>> >> > >>> >> > Derek >>> >> > >>> >> >>> >> >>> >> >>> >>> >>> > On Tue, 4 Jul 2006 17:29:29 -0700, Derek Hart wrote:
> The database process will be called about 10 times in one long routine, Do all your database stuff in a single thread and use Control.Invoke or> starting a new thread each time. But the problem is that I need the thread > to finish before code execution continues. The main reason this does not > just run on the same thread is that I need to get the darn status bar > updated, but the UI freezes up. I tried using t.Join() which does wait for > the thread to finish, but it does not allow the UI to be freed up. And I > tried setting a global variable to detect when the thread is done, but the > code after the thread just runs in a Do Loop until the variable is set, > which also freezes up the UI. Any ideas of how to get this working? Control.BeginInvoke to update your progress bar. These methods will marshall the call to the UI thread for you. A lot cleaner than these ugly hacks with Application.DoEvent loops dating from VB6. Hello derek
so you want a responsive progressbar huh :-) i use the following Delegate Sub AsynchMethodInvoker() Public Sub SetPbValue(ByVal Count As Integer) If Me.pbMain.InvokeRequired Then Dim d As New CrossThreadInvParaMB(AddressOf SetPbValue) Me.Invoke(d, New Object() {Count}) Else Me.pbMain.Value = Count End If End Sub now just call the method from your other thread and it will just work fine :-) ofcourse is pbmain the progress bar hope this helps Michel Posseth [MCP] Show quoteHide quote "Mehdi" wrote: > On Tue, 4 Jul 2006 17:29:29 -0700, Derek Hart wrote: > > > The database process will be called about 10 times in one long routine, > > starting a new thread each time. But the problem is that I need the thread > > to finish before code execution continues. The main reason this does not > > just run on the same thread is that I need to get the darn status bar > > updated, but the UI freezes up. I tried using t.Join() which does wait for > > the thread to finish, but it does not allow the UI to be freed up. And I > > tried setting a global variable to detect when the thread is done, but the > > code after the thread just runs in a Do Loop until the variable is set, > > which also freezes up the UI. Any ideas of how to get this working? > > Do all your database stuff in a single thread and use Control.Invoke or > Control.BeginInvoke to update your progress bar. These methods will > marshall the call to the UI thread for you. A lot cleaner than these ugly > hacks with Application.DoEvent loops dating from VB6. > ahum :-(
copied the wrong delegate > Delegate Sub AsynchMethodInvoker() should be Delegate Sub CrossThreadInvParaMB(ByVal val As Integer) sorry ;-) Show quoteHide quote "M. Posseth" wrote: > Hello derek > > so you want a responsive progressbar huh :-) > > i use the following > > Delegate Sub AsynchMethodInvoker() > Public Sub SetPbValue(ByVal Count As Integer) > If Me.pbMain.InvokeRequired Then > Dim d As New CrossThreadInvParaMB(AddressOf SetPbValue) > Me.Invoke(d, New Object() {Count}) > Else > Me.pbMain.Value = Count > End If > End Sub > > now just call the method from your other thread and it will just work fine > :-) > > ofcourse is pbmain the progress bar > > > hope this helps > > > Michel Posseth [MCP] > > > > > > > > "Mehdi" wrote: > > > On Tue, 4 Jul 2006 17:29:29 -0700, Derek Hart wrote: > > > > > The database process will be called about 10 times in one long routine, > > > starting a new thread each time. But the problem is that I need the thread > > > to finish before code execution continues. The main reason this does not > > > just run on the same thread is that I need to get the darn status bar > > > updated, but the UI freezes up. I tried using t.Join() which does wait for > > > the thread to finish, but it does not allow the UI to be freed up. And I > > > tried setting a global variable to detect when the thread is done, but the > > > code after the thread just runs in a Do Loop until the variable is set, > > > which also freezes up the UI. Any ideas of how to get this working? > > > > Do all your database stuff in a single thread and use Control.Invoke or > > Control.BeginInvoke to update your progress bar. These methods will > > marshall the call to the UI thread for you. A lot cleaner than these ugly > > hacks with Application.DoEvent loops dating from VB6. > >
ulong vs UInt64
Live multi-user debugging? Help! dotnet activex equivalent? Can I use an asterisk in the "Imports" statement? Accessing existing Excel instance CheckedListbox backcolor question File.Exists not working. Transferring data between datatables and between datareader and datatable How to use DataGridComboColumnStyle Beta Testers Needed for WindowsForms Component. |
|||||||||||||||||||||||