Home All Groups Group Topic Archive Search About
Author
5 Jul 2006 12:29 AM
Derek Hart
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

Author
5 Jul 2006 6:40 AM
GhostInAK
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
>
Author
5 Jul 2006 10:15 AM
M. Posseth
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
> >
>
>
>
Author
5 Jul 2006 11:03 AM
Cor Ligthert [MVP]
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

Show 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
>> >
>>
>>
>>
Author
5 Jul 2006 12:18 PM
M. Posseth
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
> >> >
> >>
> >>
> >>
>
>
>
Author
5 Jul 2006 3:14 PM
Cor Ligthert [MVP]
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



Show 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
>> >> >
>> >>
>> >>
>> >>
>>
>>
>>
Author
5 Jul 2006 4:49 PM
Michel Posseth [MCP]
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



Show 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
>> >> >
>> >>
>> >>
>> >>
>>
>>
>>
Author
5 Jul 2006 6:37 PM
Cor Ligthert [MVP]
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.

:-)

Cor

Show 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
>>> >> >
>>> >>
>>> >>
>>> >>
>>>
>>>
>>>
>
Author
5 Jul 2006 9:22 AM
Mehdi
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.
Author
5 Jul 2006 10:05 AM
M. Posseth
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.
>
Author
5 Jul 2006 10:32 AM
M. Posseth
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.
> >