【问题标题】:The calling thread must be STA, because many UI components require this while navigation in wpf调用线程必须是 STA,因为许多 UI 组件在 wpf 中导航时需要这个
【发布时间】:2012-03-05 12:16:36
【问题描述】:

我在 wpf 中做一个项目。 我从一个窗口导航到一个表单,当我导航到另一个窗口时,它会生成以下错误。 提前致谢。

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"];
    }
}

【问题讨论】:

  • 您对此错误有什么具体问题吗?注意:如果查看相关面板,您会发现几个非常相似的帖子。
  • 我想从验证表单导航到主窗口。但是发生了这个错误。我第一次遇到这种类型的错误,我尝试了使用另一个帖子中的线程的代码,但它没有帮助。 ...你能帮帮我吗?
  • 你能描述一下你对线程的使用以及哪些线程被设置为[STAThread]?
  • 不要在工作线程上创建窗口。请改用 Dispatcher.BeginInvoke。
  • 我试过 dispatcher.invoke。我应该有窗口的对象来调用调度程序对象,当我创建对象时 //mainwindow mwobj=new mainwindow();// 我得到错误“调用线程必须是 STA,因为许多 UI 组件都需要这个" 在 mainwindow.xaml.cs 中的公共 mainwindow(){....} 中。我该如何解决这个问题?

标签: wpf multithreading


【解决方案1】:
Dispatcher.BeginInvoke((Action)(() =>
        {
            if (result.Verified)
            {
                MakeReport("The fingerprint was VERIFIED.");
                Home h = new Home();
                this.Hide();
                h.Show();
            }
        })); 

【讨论】:

    【解决方案2】:

    必须在 STA 上创建 WPF 元素。您可能正面临这个问题,因为您正在尝试从非 STA 线程创建 WPF 元素。您可以通过将其单元模型设置为 STA 来将线程设置为 STA。

    【讨论】:

    • 我该怎么做?我是 wpf 的新手。
    • 对于@keftmedei 的回答和 Hans 的评论中描述的问题,您可以使用 Dispatcher.BeginInvoke。
    【解决方案3】:

    所以上面 keftmedei 的答案很好用。

    这是一个尝试从 MVVMLight RelayCommand 启动进程的完整示例

    在不使用 Dispatcher 的情况下,此 ViewFile 方法转到 Tralfamador 以访问管道工的助手人员,而无需留下转发地址,例如例外,威尔罗宾逊!!! (见冯内古特,见迷失太空……)

        /// <summary>
        /// Run a file by Process exec - use the shell file association
        /// Run it in its own thread by using the Dispatcher
        /// </summary>
        /// <param name="fileName"></param>
        [STAThread]
        public static void ProcessExecFileByName(string fileName)
        {
            try
            {
                Application.Current.Dispatcher.BeginInvoke((Action)(() =>
                {
                    ViewFile(fileName);
                }));
            }
            catch (Exception ex)
            {
                ex.PreserveStackTrace();
                var sb = new StringBuilder();
                sb.AppendLine("File to view: " + fileName);
                ex.AppendErrorData(sb, System.Reflection.MethodBase.GetCurrentMethod().Name);
                throw;
            }
        }
    
    
        /// View the file using the Shell file association 
        private static void ViewFile(string fileName)
        {
            using (new Helpers.WaitCursor())
            {
    
                try
                {
                    Logger.DebugFormat("Starting process with file {0}", fileName);
                    var proc = new Process();
                    proc.EnableRaisingEvents = true;
                    proc.Exited += new EventHandler(ProcessExecExitedHandler);
    
                    proc.StartInfo = new ProcessStartInfo()
                    {
                        FileName = fileName, //put your path here
                        UseShellExecute = true,
                        WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
                    };
                    proc.Start();
                    Logger.DebugFormat("Process started with file {0}", fileName);
                }
                // this is permissive
                catch (FileNotFoundException fileNFEx)
                {
                    ShowError(fileNFEx.Message, true, "WARN");
                }
                catch (InvalidOperationException invOpEx)
                {
                    invOpEx.PreserveStackTrace();
                    throw;
                }
                catch (IOException IOEx)
                {
                    IOEx.PreserveStackTrace();
                    throw;
                }
                catch (System.Security.SecurityException securityEx)
                {
                    securityEx.PreserveStackTrace();
                    throw;
                }
    
                catch (Exception ex)
                {
                    ex.PreserveStackTrace();
                    throw;
    
                }
                finally
                {
                    //if (!ok)
                    //{
                    //    ShowError(statusMessage);
                    //}
                }
            }
            return;
        }
    
        private static void ProcessExecExitedHandler(object sender, System.EventArgs e)
        {
    
            try
            {
                if (sender == null)
                {
                    return;
                }
                if (((Process)sender).HasExited == false)
                {
                    ((Process)sender).Kill();
                }
    
            }
            catch (Exception ex)
            {
                ex.PreserveStackTrace();
                throw;
            }
    
            Logger.DebugFormat("Process ended with file {0}", ((Process)sender).StartInfo.FileName);
            return;
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多