Click here to Skip to main content
15,880,543 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi all,

I'm writing a small desktop app that resizes images for posting online and i've hit a small problem with the interface freezing when I am performing a calculation to determine the combined converted filesize of images to be processed.

I'm performing the calculation whenever the trackbar on my app is changed with a timer and a backgroundworker.

The backgroundworker then performs the calculation and changes the value of a label on the form in a threadsafe manner.

The boolean runFileSizeCalculation is then reset back to true in the bwCalculator_RunWorkerCompleted routine.

Whilst the worker is doing it's thing though, my interface freezes. Isn't the purpose of the backgroundworker to stop this?


I'm new to desktop programming so be gentle. I'm a web developer normally I just thought this would be a bit of fun and maybe something useful I could share afterwards.

Many thanks in advance.

Ok ..... First, Thanks Rick and John for your info.

I was already using invoke to allow the update to the label and I've had a bit of a read of the other info. Here's what I've thrown together.

Private Sub tbRatio_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbRatio.ValueChanged

    lblRatio.Text = String.Format("{0}%", tbRatio.Value)
    reductionRatio = tbRatio.Value


    If filteredList IsNot Nothing Then

        If runFileSizeCalculation Then

            runFileSizeCalculation = False

            Dim t As New Thread(AddressOf ThreadingTest)
            t.Start()
        End If
    End If

End Sub

Private Sub ThreadingTest()

    Dim dueTimeSpan As New TimeSpan(0, 0, 3)
    latencyTimer = New Threading.Timer(AddressOf SetOutputFolderSize, Nothing, dueTimeSpan, infiniteTimeSpan)

End Sub


Delegate Sub SetOutputFolderSizeCallback()

Private Sub SetOutputFolderSize()

    If lblOutputSize.InvokeRequired Then
        Dim d As New SetOutputFolderSizeCallback(AddressOf SetOutputFolderSize)
        Invoke(d)
    Else

        lblOutputSize.Text = (String.Format("{0} MB", GetOutPutFolderSize(filteredList).ToString))
        runFileSizeCalculation = True
    End If

End Sub


The GetOutPutFolderSize function is the one that performs the actual calculation.

I'm still getting the same freezing problem.... Am I missing something obvious?

Thanks again.

***********************************************************************

Thanks again Rick, your working was much more sensible and has stopped the UI freeze.

The reason for using the timer was to run the function after a set delay so that when you change the trackbar value more than once in less than the time it took to calculate the foldersize it would hopefully catch only the last value and run the calculation based upon that.

Can you think of a better way of doing that?
Posted
Updated 13-Jan-10 5:52am
v3

How I usually approach this type of problem is to either spawn a new thread[^] or use the ThreadPool.QueueUserWorkItem method to use a ThreadPool[^] thread. The body of the thread will do the work and end asynchronously. If you need to change any of the Form or its child controls UI properties, be sure to call Invoke() on them. See this [^] for guidance.
 
Share this answer
 
Your code is still executing the work on the UI thread. That's why you have a pause.

Keeping tbRatio_ValueChanged the same, try something like this(may need massaging):
Dim m_outputSize As String = String.Empty
Private Sub ThreadingTest()
    Dim dueTimeSpan As New TimeSpan(0, 0, 3)        
    latencyTimer = New Threading.Timer(AddressOf SetOutputFolderSize, Nothing, dueTimeSpan, infiniteTimeSpan)
    m_outputSize = GetOutPutFolderSize(filteredList).ToString()
End Sub

Private Sub SetOutputFolderSize()        
    If lblOutputSize.InvokeRequired Then 
         Dim d As New SetOutputFolderSizeCallback(AddressOf SetOutputFolderSize)            
         Invoke(d)        
    Else            
         lblOutputSize.Text = (String.Format("{0} MB", m_outputSize))         
         runFileSizeCalculation = True         
    End If    
End Sub


[Updated to show use of the latency timer]
 
Share this answer
 
v7
Along with Rick's response, you can also create custom events that you can use to notify subscribed objects of the progress of important events within the thread. I use a thread pool, and custom events and it works great. I also would like to reiterate Rick's recommendation of the use of Invoke to allow the event handlers to update the UI.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900