c#在新线程中启动子WPF

本文关键字:启动 WPF 线程 新线程 | 更新日期: 2023-09-27 18:12:47

我正在寻找以下问题的帮助,我正在经历。

我已经花了两天时间在这个网站和谷歌上搜索,尝试了很多不同的方法来解决我的问题,到目前为止我还没有运气。我知道我还没有足够的阅读多线程,这将是我学习旅程中的下一个待办事项。我对c#相当陌生,所以请温柔一点。

我的主WPF应用程序有一个按钮,我已经标记为"INFO"。在"INFO"按钮的CLICK事件上,我需要启动一个单独的WPF,它只包含WEBBROWSER对象。我在web浏览器对象中显示我们的内部网站点。

我需要能够完成以下任务:

    我需要在自己的THREAD中启动WPF浏览器,以便即使启动了对话框,WPF也完全可用。
  1. 然后,我需要能够确保WPF在自己的线程中被重新激活,当用户点击INFO按钮时,如果线程已经在运行。
  2. 当主WPF关闭时,我需要确保所有打开的线程也被关闭。

我在寻找最简单的解决方案。

我在地方的样例代码

//在公共MainWindow()的正上方声明线程newWindowThread;

private async void btn_LaunchWPFBrowser_Click(object sender, RoutedEventArgs e)
      {
            try
            {
                    if (newWindowThread == null)
                    {
                        newWindowThread = new Thread(() =>
                        {
                            var wpfwindow = new WPF_Windows.wpf_Browser();
                            wpfwindow.Show();
                            wpfwindow.Closed += (sender2, e2) => wpfwindow.Dispatcher.InvokeShutdown();
                            // Start the Dispatcher Processing
                            System.Windows.Threading.Dispatcher.Run();
                        });
                        // Set the apartment state
                        newWindowThread.SetApartmentState(ApartmentState.STA);  //setting new thread’s apartment state to STA, this is a WPF requirement
                        newWindowThread.Start();
                    }
                    else if (newWindowThread.ThreadState == ThreadState.Running)
                    {
                        //wpfwindow.Activate();
                    }
            }
            catch (Exception ex)
            {
                string additionalMessage = "In method '" + TraceCallerClass.TraceCaller() + "' ";
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

c#在新线程中启动子WPF

给你:

private object syncGate = new object();
private Thread browserWindowThread;
private Window browserWindow;
private void btn_LaunchWPFBrowser_Click(object sender, RoutedEventArgs e)
{
    try
    {
        lock (syncGate)
        {
            if (browserWindowThread == null)
            {
                browserWindowThread = new Thread(() =>
                {
                    var wpfwindow = new WPF_Windows.wpf_Browser();
                    wpfwindow.Show();
                    wpfwindow.Closed += (sender2, e2) => wpfwindow.Dispatcher.InvokeShutdown();
                    lock (syncGate)
                        browserWindow = wpfwindow;
                    // Start the Dispatcher Processing
                    System.Windows.Threading.Dispatcher.Run();
                    lock (syncGate)
                    {
                        browserWindow = null;
                        browserWindowThread = null;
                    }
                });
                browserWindowThread.IsBackground = true;
                // Set the apartment state
                browserWindowThread.SetApartmentState(ApartmentState.STA);  //setting new thread’s apartment state to STA, this is a WPF requirement
                browserWindowThread.Start();
            }
            else if (browserWindow != null)
            {
                browserWindow.Dispatcher.BeginInvoke(new Func<bool>(browserWindow.Activate));
            }
        }
    }
    catch (Exception ex)
    {
        string additionalMessage = "In method '" + TraceCallerClass.TraceCaller() + "' ";
        MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}
protected override void OnClosed(EventArgs e)
{
    base.OnClosed(e);
    lock (syncGate)
    {
        if (browserWindow != null)
            browserWindow.Dispatcher.BeginInvoke(new Action(browserWindow.Close));
    }
}

使用Task而不是Thread以方便关闭进程。我的报价是这样的……

public interface IWinOwnerCollection
    {
        List<Window> WinOwnerCollection { get; }
    }
class MainWindow : Window, IWinOwnerCollection
    {
        public List<Window> WinOwnerCollection { get; private set; }
        Task newWindowTask;
        public MainWindow()
        {
            InitializeComponent();
            WinOwnerCollection = new List<Window>();
            this.Closed += (sender, args) =>
            {
                newWindowTask = null;
            };
        }
        private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            try
            {
                if (newWindowTask == null)
                {
                    newWindowTask = new Task(() =>
                    {
                        Dispatcher.Invoke(() =>
                        {
                            var wpfwindow = new Window1();
                            wpfwindow.WinOwner = this;
                            wpfwindow.Show();
                            wpfwindow.WinOwner.Closed += (o, args) =>
                            {
                                wpfwindow.Close();
                                //newWindowTask.Abort();
                            };
                        }, DispatcherPriority.Render);
                    });
                    newWindowTask.Start();
                }
                else if (newWindowTask.Status == TaskStatus.RanToCompletion)
                {
                    foreach (var window in WinOwnerCollection)
                    {
                        window.Activate();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

    }

浏览器窗口添加此属性:=>

public MainWindow WinOwner
        {
            get { return _winOwner; }
            set
            {
                _winOwner = value;
                if (value is IWinOwnerCollection)
                {
                    ((IWinOwnerCollection)value).WinOwnerCollection.Add(this);
                }
            }
        }