0

当我的 WPF 应用程序执行 WINWORD 进程并等待它完成时,我遇到了一种奇怪的情况(方法 WaitForExit())。

一旦用户关闭 Word,有两种可能性:

  1. 用户在几秒钟后关闭 Word,一切顺利。
  2. 用户在一分钟或更长时间后关闭 Word,并且应用程序不再刷新 UI(这几乎总是发生)。在 Process.WaitForExit() 应用程序将行添加到数据网格后立即,但它未显示在 UI 上。如果用户最小化并恢复窗口,它会变黑。但是,如果用户点击按钮,它仍然会对鼠标点击做出反应,但它不再刷新 Window UI。这可以在多台计算机上重现。

在 WinForms 中,这是肯定的。我真的很想知道 WPF 中这种行为的原因。这可能是 Process.WaitForExit() 上的 WPF UI 线程长块的问题吗?

顺便说一句,我没有设法在后台线程中启动应用程序并等待它在 UI 线程中完成(我试图显示一个在 WINWORD 关闭时会自动关闭的信息窗口)。

环境:Windows XP 和 Windows 7,.NET 4.0

4

1 回答 1

6

.NET 4.0 的变体:

void Button_Click(object sender, RoutedEventArgs e)
{
    var t = StartAndWaitProcess(@"some\document\path");
    t.ContinueWith(dummy => b.Content = "process finished",
                   TaskScheduler.FromCurrentSynchronizationContext());
}

Task StartAndWaitProcess(string path)
{
    var p = new Process();
    p.StartInfo.FileName = path;
    p.EnableRaisingEvents = true;
    var tcs = new TaskCompletionSource<bool>();
    p.Exited += (sender, args) => { tcs.SetResult(true); p.Dispose(); };
    Task.Factory.StartNew(() => p.Start());
    return tcs.Task;
}

对于 .NET 4.5,有一个更好的选择

async void Button_Click(object sender, RoutedEventArgs e)
{
    await StartAndWaitProcess(@"some\document\path");
    b.Content = "process finished";
}

StartAndWaitProcess是一样的。)


旧代码,保持一致性:

async void Button_Click(object sender, RoutedEventArgs e)
{
    var t = Task.Run(() => StartAndWaitProcess(@"some\document\path"));
    await t;
    label.Content = "process finished";
}

void StartAndWaitProcess(string path)
{
    using(var p = Process.Start(path))
        p.WaitForExit();
}

这种变体更糟,因为它不必要地阻塞了后台线程等待。

于 2013-06-18T23:27:23.160 回答