调用线程必须是STA,因为在wpf中导航时,许多UI组件都需要此线程 [英] The calling thread must be STA, because many UI components require this while navigation in wpf

查看:76
本文介绍了调用线程必须是STA,因为在wpf中导航时,许多UI组件都需要此线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在wpf中做一个项目.我从一个窗口导航到一个窗体,当我导航到另一个窗口时,它会产生以下错误.我如何才能正确地导航到另一个窗口?谢谢.

调用线程必须是STA,因为许多UI组件都需要此

Verificationform.cs

am doing a project in wpf. i navigate from a window to a form and when i navigate to another window it generate the following error.how can i navigate to the other window without error?thanks in advance.

The calling thread must be STA, because many UI components require this

verificationform.cs

if (result.Verified)
            {
                MakeReport("The fingerprint was VERIFIED.");
                Home h = new Home();
                this.Hide();
                h.Show();
            }



================================================== ========



==========================================================

public partial class Home : Window
{
    public Home()  ////######error occurs here!!!
    {

        InitializeComponent();
        labelNAME.Content = (string)Application.Current.Properties["name"];
    }
}

推荐答案

底部的这段代码对我有用.

在ASP.NET页面中,我决定将异常作为PNG图像发送给客户端,但是我也得到了异常:

"ASP.NET调用线程必须是STA,因为许多UI组件都需要STA."

底部的3条线可能会为您提供帮助.

This code at the bottom worked for me.

Inside an ASP.NET page, I decided to send the exception to the client as a PNG image, but I also got the exception:

"ASP.NET The calling thread must be STA, because many UI components require this."

The 3 thread lines at the bottom is probably what can help you.

/// <summary>
/// Converts an exception to a PNG image, and streams it to the client browser. This helps because
/// the client expects a PNG only. The client viewer doesn't show the image if an error occurred.
/// </summary>
void SendExceptionAsPNG(Exception ex) {

    /* client expects a PNG */
    Thread STAThread = new Thread(() => {

        TextBlock TextBlock = new TextBlock();
        TextBlock.Text = "Internal server error: " + ex.ToString();
        TextBlock.TextWrapping = TextWrapping.WrapWithOverflow;
        TextBlock.Foreground = new SolidColorBrush(System.Windows.Media.Colors.Red);
        TextBlock.VerticalAlignment = VerticalAlignment.Top;

        Border Border = new Border();
        Border.BorderBrush = new SolidColorBrush(System.Windows.Media.Colors.Black);
        Border.BorderThickness = new Thickness(2);
        Border.Margin = new Thickness(20);
        Border.Padding = new Thickness(20);
        Border.Child = TextBlock;
        Border.Width = 700;
        Border.Height = 700;
        Border.Arrange(new Rect(0, 0, 740, 740));

        var RTB = new RenderTargetBitmap(740, 740, 96, 96, PixelFormats.Default);
        RTB.Render(Border);

        var PNGEncoder = new PngBitmapEncoder();
        PNGEncoder.Frames.Add(BitmapFrame.Create(RTB));

        Response.Clear();
        Response.ContentType = "image/png";
        using (MemoryStream MemoryStream = new MemoryStream()) {
            PNGEncoder.Save(MemoryStream);
            byte[] Bytes = MemoryStream.ToArray();
            Response.OutputStream.Write(Bytes, 0, Bytes.Length);
        }
        Response.Flush();
        Response.End();
    });

    STAThread.SetApartmentState(ApartmentState.STA);

    STAThread.Start();

    STAThread.Join();
}



希望对您有所帮助.

马丁



I hope that helps.

Martin


不幸的是,您没有解释在哪个线程以及在何处引发异常该怎么做.

基本上,这是您可以考虑的内容:

一些API需要STA线程.特别是WPF应用程序的入口点(通常,静态方法Main在STA线程中运行.如果将线程更改为MTA,WPF本身将不起作用,因为它也是基于STA的. br/>
如果创建其他线程,则始终可以在任何单元模型中运行它,但不能在线程本身中对其进行更改.您可以在用于创建其他线程的线程中执行操作,例如:

Unfortunately, you did''t explain what do you do in what thread and where the exception is thrown.

Basically, this is what you can take into account:

Some APIs require STA thread. In particular, the entry point of WPF application (normally, the static method Main is run in the STA thread. If you change the thread to MTA, WPF itself won''t work, as it also is based on STA.

If you create some other thread, you can always run it in any of the apartment model, but you cannot change it in a thread itself. You can do in in a thread which you used for creation of other thread, for example:

System.Threading.Thread thread = new System.Threading.Thread(() => {
    // the body of thread method comes here (anonymous in this example, please see below)
    // don't try to change apartment state here
    // but you can call:
    var apartmentState = Thread.System.Threading.Thread.CurrentTread.GetApartmentState();
    // just to check up the apartment state
});
thread.GetApartmentState(System.Threading.ApartmentState.STA);

//...

thread.Start(); // will be executed in specified apartment state



请参阅:
http://msdn.microsoft.com/en-us/library/system.threading. thread.aspx [^ ],
http://msdn.microsoft.com/en-us/library/system. threading.thread.setapartmentstate.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/system.threading. apartmentstate.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/bd9cdfyx.aspx [ ^ ].

在实际的代码中,您可能不应该创建类似的线程.我已经显示了此示例,只是为了说明如何使用公寓状态.我总是建议使用线程包装器,这有很多很好的理由,我在过去的解决方案中曾解释过,其中提供了框架类来包装线程:
如何将ref参数传递给线程 [ ^ ],
启动后更改线程(生产者)的参数 [ ^ ].

—SA



Please see:
http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx[^],
http://msdn.microsoft.com/en-us/library/system.threading.thread.setapartmentstate.aspx[^],
http://msdn.microsoft.com/en-us/library/system.threading.apartmentstate.aspx[^],
http://msdn.microsoft.com/en-us/library/bd9cdfyx.aspx[^].

In real code, you should not probably create threads like that; I''ve shown this sample only to show how to work with apartment states. I always advise to use thread wrappers, by many good reasons explained in my past solutions where I offer a skeleton classes to wrap threads:
How to pass ref parameter to the thread[^],
change paramters of thread (producer) after it started[^].

—SA


这篇关于调用线程必须是STA,因为在wpf中导航时,许多UI组件都需要此线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆