任务运行时图片框动画冻结 [英] PictureBox animation freezing while Task running

查看:38
本文介绍了任务运行时图片框动画冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当长时间运行的操作运行时,我的 Winforms 应用程序在图片框中显示动画 gif.但是,它在等待任务完成时冻结:

My Winforms application shows an animated gif inside a picturebox while long running operations run. However, it freezes while waiting for the completion of the task:

Public Class MyUserControl
    Sub Initialize()
        Dim folderscantask = Task.Factory.StartNew(
            Function() EwsManagedApiScanFolderHierarchy(),
            TaskCreationOptions.LongRunning
            )
        folderdictask.Wait()
        Dim folderscanresult = folderscantask.Result
    End Sub

    Function EwsManagedApiScanFolderHierarchy() As Dictionary(Of String, String)
        'Performs a long, recursive operation involving a
        'Microsoft.Exchange.WebServices.Data.ExchangeService object
    End Function
End Class

我应该怎么做才能保持 PictureBox 的动画运行?

What should I do differently in order to keep PictureBox's animation running?

这是对我的问题的更完整描述,这次我使用了 Async/Await(因为我被教导 Task.Wait() 会阻塞调用者线程).现在,动画运行良好,直到它第一次到达 MyUserControl.BuildFolderMenus(),然后它冻结.这是不可避免的吗?我的意思是,动画不是在专用线程中运行吗?

This is a more complete description of my problem, and this time I used Async/Await (since I was taught that Task.Wait() would block the caller thread). Now, animation moves fine until it reaches MyUserControl.BuildFolderMenus() for the first time, then it freezes. Is this inevitable? I mean, don't animations run in a dedicated thread?

Public Class MyForm : Inherits Form

    'Form has a PictureBox named PictureBoxWaiting that shows an animated gif

    Public Async Sub MyButton_Click(sender as Object, e as EventArgs) Handles MyButton.Click
        PictureBoxWaiting.Show()
        PictureBoxWaiting.BringToFront()
        Await MyUserControl1.Initialize()
        PictureBoxWaiting.Hide()
        MyUserControl1.Show()
    End Sub

End Class

Public Class MyUserControl

    Public Async Function Initialize() As Task
        Dim folderdic = Await GetFolderHierarchyAsync()
        BuildFolderMenus(ToolStripDropDownButtonFolders, folderdic)
    End Function

    Public Async Function GetFolderHierarchyAsync() As Task(Of Dictionary(Of String, String))
        Return Await Task.Factory.StartNew(
            Function() EwsManagedApiScanFolderHierarchy(),
            TaskCreationOptions.LongRunning
            )
    End Function

    Function EwsManagedApiScanFolderHierarchy() As Dictionary(Of String, String)
        'Performs a long, recursive operation involving a
        'Microsoft.Exchange.WebServices.Data.ExchangeService object
    End Function

    Private Sub BuildFolderMenus(menu As ToolStripDropDownItem, dic As Dictionary(Of String, String))
        'This reads the dictionary containing the folder hierarchy
        'and recursively adds menu items in order that folders´
        'subfolders correspond to subitems inside an item
        '
        'This must run in UI thread since it creates UI controls
    End Sub

End Class

推荐答案

您通过调用 Task.Wait() 阻塞了 UI 线程.您需要使用 Asunc/Await 模式.例如创建一个这样的方法:

You are blocking the UI thread by calling Task.Wait(). You need to use Asunc/Await pattern. For example create a method like this:

Public Async Function MyFunction() as Task
    Await Task.Run(Sub()
                        ' Do something non-UI which is time-consuming
                        ' This code runs in another thread without blocking UI
                        ' For example Thread.Sleep(5000)
                    End Sub)
    'The code here runs is UI thread
End Function

然后作为用法:

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Await MyUserControl1.MyFunction()
End Sub

然后你会看到,虽然你在MyFunction中有一个耗时的任务,但是在任务运行时UI不会被阻塞.

Then you will see, although you have a time-consuming task in MyFunction, but the UI will not be blocked while the task is running.

这篇关于任务运行时图片框动画冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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