如何在 WPF 中处理多个 windows

How to work on multiple windows in WPF

我有一个 C# WPF 应用程序,它执行一些数据处理。由于应用程序需要一些时间来进行处理,有时 window 会冻结。所以我基本上是想找到一种方法,让用户不会惊慌失措。我正在考虑在处理一些统计数据时生成第二个 window,而主要 window 留在后台或隐藏直到处理完成,以效果更好者为准。也许这会防止事情冻结或至少隐藏它?

目前,我尝试在处理开始时使用以下代码创建第二个 window...但我不确定如何为它编辑 XAML。我正在使用 VS 2013,并且只看到 XAML 作为我的初始 window。任何帮助将不胜感激!

    Window win = new Window();
    win.Show();
    win.Activate();

您应该 运行 在不同的线程或后台处理您的长时间 运行ning。

一个简单的方法是使用 BackgroundWorker

var bw = new BackgroundWorker();
bw.DoWork += (s, e) =>
    {
        //put the long running process in here.
    };

bw.RunWorkerAsync();

上次我在 WPF 中工作时,我认为它不能很好地处理多个 windows。即便如此,它也不能解决你的问题。您的问题是您的 运行 长任务与 UI.

在同一线程上 运行

您的问题的真正解决方案是异步编码。有关背景信息,请查看 .net TPL 以及 async/await 功能。这些分别在 .net 4.0 和 4.5 中可用。

这是您将如何使用它的示例。

private async void BeginProcessingAsync(Data d)
{
    //Show to user that task is running
    this.IsLoading = true; // Show a loading icon or something.

    //Execute the long running task asynchronously
    await Task.Run(() =>  LongRunningMethod(d));

    //Anything after the await line will be executed only after the task is finished.
    this.IsLoading = false;
    DoSomethingWithFinishedData(d);
}

您 运行 遇到的问题是您有 UI 线程试图完成所有工作。虽然 UI 线程正在进行长期处理,但它无法更新您的 window。

您要做的是让一个单独的线程处理后台进程。在用户想要关闭 windows 或取消当前进程之前,此方法运行良好。那时您必须开始担心 UI 线程和工作线程之间的交互。为此,.Net 为我们提供了一种称为取消令牌的东西,它将允许我们(如果我们愿意)手动跟踪何时取消进程。

取消令牌很容易与 Task class 一起使用。您可以使用 await/async 对其进行补充,这样您就不必手动检查以等待任务完成。

您的选项将根据您当前的框架而有所不同。