在单独的线程中启动 WPF 窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23297133/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:38:25  来源:igfitidea点击:

Launching a WPF Window in a Separate Thread

c#wpfmultithreading

提问by Cyberguille

I'm using the following code for to open a window in a separate thread

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

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
    }
}

If I use this code in a method, it works. But when I use it as follows, I get an error:

如果我在方法中使用此代码,它会起作用。但是当我按如下方式使用它时,出现错误:

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
    }
}

It throws the following error:

它引发以下错误:

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

What is the cause of this?

这是什么原因?

采纳答案by Cyberguille

@d.moncada, @JPVenson, @TomTom sorry for everyone, espetially to @d.moncada, your answer made me realize my true error, indeed if run once until my code works. But my really problem is that i try to push button1_Click in two ocation, really i take a timer that called a method with the line of the

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

 private void button1_Click(object sender, RoutedEventArgs e)

Now the solution of my problem is Detecting a Thread is already running in C# .net?

现在我的问题的解决方案是检测线程是否已经在 C# .net 中运行?

回答by d.moncada

I believe the problem is that you are setting the ApartmentStateafter the Threadas started running.

我认为,问题是,你正在设置ApartmentStateThread的开始运行。

Try:

尝试:

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();
    }
}

回答by Venson

why you trying to do this? there is (nearly)no reason to run a 2end UI thread inside you application ... if you want a non Modal new Window, instantiate you window and call show.

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

Why nearly? Because this is a very complex topic and unless you have a huge budged to develop exactly this behavior, you can live without it.

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