Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: VB Threading WinForm
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 13-Jan-10 4:57am
Edited 13-Jan-10 6:52am
v3
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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.
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

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]
  Permalink  
v7
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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.
  Permalink  
v2

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

  Print Answers RSS
0 BillWoodruff 360
1 Mathew Soji 309
2 Maciej Los 270
3 DamithSL 225
4 Afzaal Ahmad Zeeshan 202
0 OriginalGriff 6,249
1 Sergey Alexandrovich Kryukov 5,853
2 DamithSL 5,183
3 Manas Bhardwaj 4,673
4 Maciej Los 3,865


Advertise | Privacy | Mobile
Web04 | 2.8.1411019.1 | Last Updated 13 Jan 2010
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100