【问题标题】:Launching a WPF Window in a Separate Thread在单独的线程中启动 WPF 窗口
【发布时间】:2014-04-25 15:24:25
【问题描述】:

我正在使用以下代码在单独的线程中打开一个窗口

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        Thread newWindowThread = new Thread(new ThreadStart(() =>
        {
            // Create and show the Window
            Config tempWindow = new Config();
            tempWindow.Show();
            // Start the Dispatcher Processing
            System.Windows.Threading.Dispatcher.Run();
        }));

        // Set the apartment state
        newWindowThread.SetApartmentState(ApartmentState.STA);
        // Make the thread a background thread
        newWindowThread.IsBackground = true;
        // Start the thread
    }
}

如果我在方法中使用此代码,它会起作用。但是当我如下使用它时,我得到一个错误:

public partial class App : Application
{
    #region Instance Variables
    private Thread newWindowThread;

    #endregion

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        newWindowThread = new Thread(new ThreadStart(() =>
        {
            // Create and show the Window
            Config tempWindow = new Config();
            tempWindow.Show();
            // Start the Dispatcher Processing
            System.Windows.Threading.Dispatcher.Run();
        }));
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        // Set the apartment state
        newWindowThread.SetApartmentState(ApartmentState.STA);
        // Make the thread a background thread
        newWindowThread.IsBackground = true;
        // Start the thread
    }
}

它会抛出以下错误:

System.Threading.ThreadStateException
The state of the thread was not valid to execute the operation

这是什么原因?

【问题讨论】:

  • 你只点击过一次吗? (一个线程不能启动两次)

标签: c# wpf multithreading


【解决方案1】:

@d.moncada,@JPVenson,@TomTom 对不起大家,尤其是 @d.moncada,你的回答让我意识到我真正的错误,如果运行一次直到我的代码工作。但我真正的问题是我尝试在两个位置按下 button1_Click,实际上我使用了一个计时器,该计时器使用

行调用了一个方法
 private void button1_Click(object sender, RoutedEventArgs e)

现在我的问题的解决方案是Detecting a Thread is already running in C# .net?

【讨论】:

    【解决方案2】:

    我认为问题在于您将ApartmentState 设置在Thread 之后开始运行。

    试试:

    public partial class App : Application
    {
        #region Instance Variables
        private Thread newWindowThread;
    
        #endregion
    
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            newWindowThread = new Thread(new Thread(() =>
            {
                // Create and show the Window
                Config tempWindow = new Config();
                tempWindow.Show();
                // Start the Dispatcher Processing
                System.Windows.Threading.Dispatcher.Run();
            }));
            // Set the apartment state
            newWindowThread.SetApartmentState(ApartmentState.STA);
            // Make the thread a background thread
            newWindowThread.IsBackground = true;
        }
    
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            // Start the thread
            newWindowThread.Start();
        }
    }
    

    【讨论】:

      【解决方案3】:

      你为什么要这么做? (几乎)没有理由在您的应用程序中运行 2end UI 线程...如果您想要一个非模态新窗口,请实例化您的窗口并调用 show

      为什么差不多?因为这是一个非常复杂的话题,除非你有很大的预算来开发这种行为,否则你可以没有它。

      【讨论】:

      • -1。没理由?见过运行 6 个屏幕的金融交易应用程序吗?每个屏幕(这是一个窗口)有一个独立的消息泵非常好。单独窗口的单独线程的好处是所有“UI是单线程的”然后适用于每个窗口的bassis,这可以帮助并行化很多。所以是的,有原因 - 它们是边缘原因,我承认它们不适用于大多数程序,但尝试这样做的人很可能是“我需要它”的人之一。大多数人甚至不知道这是可能的。
      • @JPVenson这不是我的代码完整,我需要主窗口继续执行其他代码并抛出这个带有警报消息的窗口,并使用一个窗口而不是一个消息框,因为这个想法是显示一个大窗户,大字,色彩浓
      • 只是“技能”的问题......我在一家公司工作,我们处理千兆字节的数据,但只有 2 个非常复杂的 Windows,一切都处于非常高的性能水平(使用 Thredding但不像“把所有东西都放在一个线程中并快乐”^^)。如果您的应用程序确实需要一个线程来处理每个单独的 UI 渲染,您可能应该重新考虑/重构您的软件 Desgin。如果您需要复杂的 UI 渲染,您可以在线程中创建/修改数据,然后让 UI 渲染。 90% 有更好的方法,然后将内容放入线程中。
      • @JPVenson :嗯,你可能会建议 chrome 开发团队重构他们的代码,然后...... chrome 不仅每个 UI 使用一个线程,而且每个 UI 使用一个进程。依赖他人代码的良好行为并不是真正的健壮和可持续的。除非你公司的每个人都是他妈的优秀程序员:)
      • @JPVenson :我不知道 Guillermo 的应用程序的大小,但如果 UI 渲染良好并且将来不会成为问题,那么没有理由为UI 所以我同意你的看法。但是如果 UI 的性能我怀疑,那么您可以使用 STA 线程。所以我认为人们只是从其他网站复制代码并编写类似的应用程序。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-21
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      相关资源
      最近更新 更多