调用线程必须是STA,因为在WPF中许多UI组件都需要此错误.在form.show() [英] The calling thread must be STA, because many UI components require this error In WPF. On form.show()

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

问题描述

首先,我已经在网站上阅读了一些类似问题的答案,但是老实说,我发现它们有些混乱(由于我缺乏经验,而不是答案!).我正在使用FileSystemWatcher()类来监视文件夹中是否有正在创建/更改的文件.事件一旦发生,我便想在项目中加载另一个表单.当新表单上的构造函数尝试执行时,我没有加载表单,而是得到了错误.我仅使用一个线程-我没有尝试在其他线程下加载表单.我的代码如下

Firstly I have read several answers to similar questions on the site but to be honest I find them a bit confusing (due to my lack of experience rather than the answers!). I am using a the FileSystemWatcher() class to monitor a folder for a file being created/changed. Once the event occurs I then want to load another form in the project. Instead of loading the form I get the error when the constructor on the new form is trying to execute. I am only using one thread - I'm not attempting to load the form under a different thread. My code is as follows

 //MainWindow
 public static void FolderWatcher()
  {
        FileSystemWatcher fsWatcher = new FileSystemWatcher();
        fsWatcher.Path = "C:\\dump";
        fsWatcher.Filter = "*";
        fsWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
        | NotifyFilters.FileName | NotifyFilters.DirectoryName;
        fsWatcher.Created += new FileSystemEventHandler(OnChanged);
        fsWatcher.EnableRaisingEvents = true;    
  }

  public static void OnChanged(object source, FileSystemEventArgs e)
  {
       var imagePreview = new ImagePreview();
       imagePreview.Show();
  }


  //SecondForm
  public partial class ImagePreview : Window
  {
        public ImagePreview()
        {
              InitializeComponent(); //error occurs here
        }
  }

希望您能提供帮助,在此先感谢您.

Hope you can help, many thanks in advance.

推荐答案

您使用多少线程无关紧要.只是有一条规则:创建UI的任何线程都必须是STA.

It doesn't matter how many threads you are using. There is just a rule: any thread where you are creating UI must be STA.

如果只有一个线程,则该线程必须是STA. :-)为了使主线程成为STA,您需要在Main上使用STAThread属性:

In case you have only one thread, this very one has to be STA. :-) In order to make the main thread an STA, you need to use the STAThread attribute on your Main:

[STAThread]
static void Main(string[] args)
{
    // ...

如果仅创建标准WPF应用程序,则主线程已被标记为required属性,因此无需更改.

If you just create a standard WPF application, the main thread is already marked with the needed attribute, so there should be no need for change.

请注意,来自FileSystemWatcher的事件可能来自框架内部创建的其他线程. (您可以通过在OnChanged中设置断点来进行检查.)在这种情况下,您需要将窗口创建转发到STA线程.如果您的应用程序是WPF应用程序,则可以通过以下方式完成:

Beware that the events from FileSystemWatcher may come from some other thread which is internally created by the framework. (You can check that by setting a breakpoint in OnChanged.) In this case, you need to forward the window creation to an STA thread. In case your application is a WPF application, it's done this way:

public static void OnChanged(object source, FileSystemEventArgs e)
{
    var d = Application.Current.Dispatcher;
    if (d.CheckAccess())
        OnChangedInMainThread();
    else
        d.BeginInvoke((Action)OnChangedInMainThread);
}

void OnChangedInMainThread()
{
    var imagePreview = new ImagePreview();
    imagePreview.Show();
}

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

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