防止Windows窗体上的UI冻结. [英] Preventing UI freeze on windows form.

查看:125
本文介绍了防止Windows窗体上的UI冻结.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我正在编写一个小型桌面应用程序,该应用程序会调整图像大小以便在线发布,并且在执行计算以确定要处理图像的合并转换文件大小时遇到​​界面冻结的小问题.

只要使用计时器和后台工作人员更改应用程序上的轨迹栏,我就会执行计算.

然后,背景工作人员执行计算并以线程安全的方式更改表单上标签的值.

然后在bwCalculator_RunWorkerCompleted例程中将布尔runFileSizeCalculation重置为true.

尽管工作人员正在执行此操作,但我的界面死机了.后台工作人员的目的不是阻止这一点吗?


我是桌面编程的新手,所以要保持柔和.我通常是Web开发人员,我只是觉得这会很有趣,也许以后我可以分享一些有用的信息.

提前非常感谢.

好吧...首先,谢谢里克和约翰提供的信息.

我已经在使用invoke来允许更新标签,并且我对其他信息有所了解.这是我一起扔的东西.

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



GetOutPutFolderSize函数是执行实际计算的函数.

我仍然遇到同样的冻结问题....我缺少明显的东西吗?

再次感谢.

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

再次感谢Rick,您的工作更加明智,并且已停止UI冻结.

使用计时器的原因是要在设置的延迟后运行该函数,以便在更改轨迹栏值的时间少于在计算文件夹大小所花费的时间中多次更改后,它希望仅捕获最后一个值并根据以下内容运行计算在那之上.

您能想到一种更好的方法吗?

解决方案

我通常如何处理这种类型的问题是要么生成一个新的线程池 [ [



[已更新,显示了使用延迟计时器]


随着Rick的响应,您还可以创建自定义事件,该事件可用于向订阅对象通知重要事件的进度.线程.我使用线程池和自定义事件,效果很好.我还要重申里克关于使用Invoke允许事件处理程序更新UI的建议.


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?

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.


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]


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.


这篇关于防止Windows窗体上的UI冻结.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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