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