首先,我已经阅读了网站上类似问题的几个答案,但说实话,我发现它们有点令人困惑(由于我缺乏经验而不是答案!).我正在使用FileSystemWatcher()类来监视正在创建/更改的文件的文件夹.一旦事件发生,我就想在项目中加载另一个表单.而不是加载表单我在新表单上的构造函数尝试执行时得到错误.我只使用一个线程 - 我不是试图在不同的线程下加载表单.我的代码如下
//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
}
}
Run Code Online (Sandbox Code Playgroud)
希望你能提前帮助,非常感谢.
Vla*_*lad 22
无论您使用多少线程都无关紧要.只有一个规则:创建UI的任何线程都必须是STA.
如果您只有一个线程,那么这个线程必须是STA.:-)为了使主线程成为STA,您需要使用以下STAThread属性Main:
[STAThread]
static void Main(string[] args)
{
// ...
Run Code Online (Sandbox Code Playgroud)
如果您只是创建一个标准的WPF应用程序,主线程已经标记了所需的属性,因此不需要更改.
请注意,来自的事件FileSystemWatcher可能来自框架内部创建的其他一些线程.(您可以通过设置断点来检查OnChanged.)在这种情况下,您需要将窗口创建转发到STA线程.如果您的应用程序是WPF应用程序,它就是这样做的:
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();
}
Run Code Online (Sandbox Code Playgroud)
您正在从非UI线程调用UI内容(即从非UI线程FileSystemWatcher触发事件).
我编写了一个扩展方法,我在我唯一的WPF项目(ugh)中使用了它:
public static class DispatcherEx
{
public static void InvokeOrExecute(this Dispatcher dispatcher, Action action)
{
if (dispatcher.CheckAccess())
{
action();
}
else
{
dispatcher.BeginInvoke(DispatcherPriority.Normal,
action);
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以现在,在使方法非静态以便您可以访问MainWindow Dispatcher之后,您可以在事件回调中执行此操作:
public void OnChanged(object source, FileSystemEventArgs e)
{
this.Dispatcher.InvokeOrExecute(()=>{
var imagePreview = new ImagePreview();
imagePreview.Show();
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26708 次 |
| 最近记录: |