首页 > 解决方案 > 在 WPF 的另一个对话框中运行繁重任务时运行启动对话框

问题描述

我正在尝试执行标题中描述的任务。HeaviWindow 执行一些繁重的任务,因此在任务完成之前不会显示。这次我想用动画加载器显示一个启动画面。

到目前为止,我使用了以下结构:

private RunHeavyTask()
{
    ShowSplashScreen("Please wait...");
    var dialog = new HeaviWindow();
    dialog.ShowDialog();
}

private void ShowSplashScreen(string str)
{
    Thread newWindowThread = new Thread(new ParameterizedThreadStart(ThreadStartingPoint));
    newWindowThread.SetApartmentState(ApartmentState.STA);
    newWindowThread.IsBackground = true;
    newWindowThread.Start(str);
}

private void ThreadStartingPoint(object str)
{
    splash = new WaitWindow((string)str);
    splash.Show();
    System.Windows.Threading.Dispatcher.Run();
}

但突然发现,在运行线程时,所有其他后台线程都停止工作。

我试图Task用于此目的:

private void ShowSplashScreen(string str)
    Task.Run(() => 
    {
        Application.Current.Dispatcher.Invoke(delegate
        {
            splash = new WaitWindow((string)str);
            splash.ShowDialog();
        });
    });
}

但是在繁重的对话框完成任务之前不会显示启动画面。如果我使用相同的结果BackgroundWorker

所以我的问题 - 我如何在另一个任务中运行繁重的任务时显示启动对话框。初始对话框使用一些动画,因此需要更新。

标签: c#wpfmultithreadingtask

解决方案


尝试这个:

Window splash;
private void RunHeavyTask()
{
    ShowSplashScreen("Please wait...");
    //simulate "heavy task" by sleeping for 5 seconds
    Thread.Sleep(5000);
    //close the splash window
    splash.Dispatcher.BeginInvoke(() => splash.Close());
}

private void ShowSplashScreen(string str)
{
    Thread newWindowThread = new Thread(new ThreadStart(() =>
    {
        SynchronizationContext.SetSynchronizationContext(
            new DispatcherSynchronizationContext(
                Dispatcher.CurrentDispatcher));

        //pass str to your custom Window here...
        splash = new Window() { Content = new ProgressBar() { IsIndeterminate = true } };
        splash.Closed += (s, e) =>
           Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);

        splash.Show();
        Dispatcher.Run();
    }));
    newWindowThread.SetApartmentState(ApartmentState.STA);
    newWindowThread.IsBackground = true;
    newWindowThread.Start();
}

当调用的线程被阻塞ProgressBar时,它将在后台线程上显示一个不确定的窗口。RunHeavyTask()


推荐阅读