如何在不破坏应用程序的情况下中止线程(在其中运行表单)?

时间:2018-01-23 14:51:22

标签: c# wpf multithreading

我为我的wpf应用程序创建了一个启动画面窗体。我正在尝试在加载主窗体时显示启动画面。我在主窗体的构造函数中创建了一个线程,它显示了启动画面,当主窗体完全加载时,该线程被中止。 问题是SplashThread.Abort()崩溃了我的应用程序。因此,我的启动画面或编码方法有问题。我想仅显示要加载的主窗体所花费的时间的启动画面。 以下是我的一段代码。

private Thread splashThread;
 public App()
        {
            splashThread = (new Thread(() => (new BDTSplashscreen()).ShowDialog()));
            splashThread.SetApartmentState(ApartmentState.STA);
            splashThread.Start();

            this.Loaded += App_Loaded;
            this.Closing += App_Closing;
            try
            { 
             //My Stuff
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Message);
            }
        }


 private void App_Loaded(object sender, RoutedEventArgs e)
        {
            splashThread.Abort();
            this.Activate();
        }

3 个答案:

答案 0 :(得分:2)

此解决方案可能不适合您,但可能有助于其他人。

如果您的启动画面很简单,即只有没有动态文本的图像,那么最简单的实现方法是将图像添加到项目中并将构建操作更改为 SplashScreen < / strong>在“属性”窗格中。

这将创建一个非常轻量级的启动画面,在您启动应用程序时启动。它使用非托管Win32,因此它将比基于WPF的启动屏幕更快地显示,它必须等待加载几个程序集并将一些代码加载到JIT。

当您显示主窗口时,启动画面将自动隐藏,并具有良好的淡出效果。它快速而简单。

您甚至可以将这个简单的启动画面与更高级的启动画面结合起来。首先显示简单的一个,然后使用相同的大小,位置和背景图像启动自己的图像。随着简单的淡出,它应该看起来像额外的内容正在消失。请参阅@ mm8的答案,了解如何处理线程。

答案 1 :(得分:0)

您可以覆盖OnStartup的{​​{1}}方法,在后台线程上显示启动画面,保持对启动画面窗口的引用,然后在主窗口加载后关闭它。像这样:

App.xaml.cs

答案 2 :(得分:0)

我就这样做了:

  • 使用此xaml和代码创建一个新视图:

    <Grid>
       <Label x:Name="ProgressMessage" Background="LightSteelBlue" Height="28" Margin="19,0,17,15" VerticalAlignment="Bottom"
           Foreground="White" ></Label>
    
    </Grid>
    
    public partial class Splash : Window
    {
        public Splash()
        {
            InitializeComponent();
        }
    
        async public Task ReceiveMessageAsync(string message)
        {
            await Dispatcher.InvokeAsync(() =>
            {
                ProgressMessage.Content = message;
            });
        }
    
        public void ReceiveMessage(string message)
        {
            ProgressMessage.Content = message;
    
        }
    }
    
  • 然后在您的主要方法中调用它:

    splash = new Splash();
    splash.Show();
    
  • 完成您的任务并使用接收消息功能显示加载任务的进度:

    splash.ReceiveMessage("I'm Loading !!");
    
  • 然后,当您的加载任务完成后,您只需使用以下命令关闭它:

    splash.Close();
    

并启动您的MainWindow。

只是几个笔记:

您的main方法当然应该设置为应用程序的Start方法。 您的主要方法也应该包含在此:

Thread app = new Thread((ThreadStart)delegate
            {
            });
            app.SetApartmentState(ApartmentState.STA);
            app.Start();