长时间运行命令期间WPF窗口无响应

时间:2014-03-21 15:42:49

标签: wpf vb.net multithreading

我认为这实际上并没有发生,但似乎我的WPF应用程序(窗口)没有异步调用Sub,或者看起来像这样的东西......用例非常简单:

wpfw = WPF窗口

StatusLeft = wpfw上的文本框

cmds =在wpfw类中实例化的命令类,用于存储所有窗口命令(subs)。该 wpfw实例在构造函数中传递给它。

UpdateStatusLeft = cmds中的Sub,如下所示:

Private Sub UpdateStatusLeft(UpdateText As String)
    Try
        Me.wpfw.Dispatcher.Invoke(CType(Sub() Me.wpfw.StatusLeft.Text = UpdateText, Action))
    Catch ex As Exception
        [...]
    End Try
End Sub

以上工作,但只在cmds中长时间运行的子菜单完成后才更新主窗口。调用长时间运行的命令并不特别:

(XAML)
 <MenuItem Header="Process Files" Click="mnuReference_ProcessFiles"/>

在wpfw中,点击的处理程序( mnuReference_ProcessFiles )是这样的:

Private Sub mnuReference_ProcessFiles(sender As Object, e As RoutedEventArgs)
    Me.cmds.ParseFiles()
End Sub

现在,只要wpfw,cmds就会被实例化,而它所指向的sub( mnuReference_ProcessFiles )就像这样:

Public Sub ParseFiles() Implements Icmds.ParseFiles
    Try
        Dim fu As FileUtils = New FileUtils()
        Me.UpdateStatusLeft("Starting Batch 1...")
        ipu.ParseFile(".\batch1")
        Me.UpdateStatusLeft("Starting Batch 2...")
        ipu.ParseFile(".\batch2")
[...]

上面,“ Me.UpdateStatusLeft ”位于cmds类中。实际上,我在主窗口调用的每个类中都放置了一个Sub UpdateStatusLeft(包括它自己的类!),然后将wpfc 实例传递给每个命令/处理类。

如果你试图直接更新textarea而不是wpfw的另一个线程/类,你会得到一个线程错误 - 这就是为什么我使用 Dispatcher.Invoke(...

净度:

这些命令都按预期启动,并且做得很好。这从来都不是问题。

问题是试图找到一种方法来更新顶级/原始UI线程的textarea,因为这些任务进展,因此用户不会入睡或认为程序已崩溃等。

2 个答案:

答案 0 :(得分:3)

主应用程序调度程序使用UI线程,因此长时间运行的进程仍将锁定UI线程

典型的解决方案是在后台线程中运行长时间运行的进程,然后使用调度程序在主线程完成后更新UI对象。

或者,如果您使用类似Task Parallel Library的内容,它允许您为UI线程安排任务,并完全绕过调度程序。这是一个例子:

Task.Factory
    .StartNew(() => 
    {
        // This runs in a background thread
        return GetLongRunningProcessResults();
    })
    .ContinueWith.StartNew((t) => 
    {
        // This runs in the UI thread because of the
        // TaskScheduler.FromCurrentSynchronizationContext parameter
        UpdateUI(t.Result);
    }, TaskScheduler.FromCurrentSynchronizationContext());

答案 1 :(得分:0)

Tasks.Run的通话中将代码包裹在ParseFiles

如果您希望应用程序保持响应,则必须在主线程之外的另一个线程中执行密集型任务。