我知道已经有很多问题被问到了。但是,提供的有关委派的解决方案并不是我要使用代码的内容,因为我正在使用4.5版本,而且Dispatcher方法似乎略有更改。除此之外,近十年后,我第一次接触到了互联网。
在我的WPF项目中,我实际要做的是将文本框的文本附加到主窗口中,以显示状态/日志。这是在名为Logger
的singleton类中。这个类的主要静态函数是log((,它接受一个字符串,该字符串需要用一行添加到文本框中
txt.AppendText(msg);
做了一些研究后,我把它改成了
Dispatcher.CurrentDispatcher.Invoke(() =>
{
txt.AppendText(msg);
});
但我还是犯了同样的错误。这里出了什么问题?还有别的事要做吗?因为我在另一个singleton类内部从FileSystemEventHandler
调用这个Logger.log()
。
private void somethingChanged(object sender, FileSystemEventArgs e)
{
Logger.log("File: " + e.FullPath + " " + e.ChangeType);
}
下面是我的Logger
类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Threading;
namespace httpclientui.comps
{
class Logger
{
private static TextBox txt;
private Logger() { }
public static void setup(TextBox t){
txt = t;
}
public static void clear()
{
if (txt == null)
{
return;
}
txt.Clear();
}
public static void log(String msg, bool addNewLineChar = true)
{
if (txt == null)
{
return;
}
Dispatcher.CurrentDispatcher.Invoke(() => {
txt.AppendText(msg);
});
}
}
}
这是我的主窗口,只有一个名为txtMessage的文本框控件。
public partial class MainWindow : Window
{
private String folderToWatch;
public MainWindow()
{
InitializeComponent();
initialize();
}
private void initialize()
{
Logger.setup(txtMessage);
Logger.clear();
Logger.log("Launched");
folderToWatch = "E:\folder\subfolder";
Watcher.Instance.setup(folderToWatch);
Watcher.Instance.start();
}
}
}
下面是我的Watcher类,它有FileSystemWatcher对象来监视其中一个文件夹,每当该文件夹内发生诸如添加/删除文件和重命名文件之类的事情时,都需要记录在该文本框中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace httpclientui.comps
{
class Watcher
{
private String path;
//https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
private FileSystemWatcher dog;
private static Watcher instance;
private Watcher()
{
//dog = new FileSystemWatcher()
}
public static Watcher Instance
{
get
{
if (instance == null)
{
instance = new Watcher();
}
return instance;
}
}
public void setup(String folderPath)
{
path = folderPath;
dog = new FileSystemWatcher(folderPath);
Logger.log("setting up to watch folder: " + folderPath);
dog.Changed += new FileSystemEventHandler(somethingChanged);
dog.Created += new FileSystemEventHandler(somethingChanged);
dog.Deleted += new FileSystemEventHandler(somethingChanged);
dog.Renamed += new RenamedEventHandler(somethingRenamed);
}
public void start()
{
Logger.log("starting to watch folder");
dog.EnableRaisingEvents = true;
}
public void pause()
{
dog.EnableRaisingEvents = false;
}
public void stop()
{
dog.EnableRaisingEvents = false;
}
private void somethingChanged(object sender, FileSystemEventArgs e)
{
Logger.log("File: " + e.FullPath + " " + e.ChangeType);
}
private void somethingRenamed(object sender, RenamedEventArgs e)
{
Logger.log("File: " + e.OldFullPath + " renamed to " + e.FullPath);
}
}
}
乍一看,您似乎没有将Clear()
方法调用编组到Dispatcher。这就是可能引发异常的原因-对DispatcherObjects(包括所有控件(的所有访问都必须由Dispatcher线程完成。
此外,您希望使用Application.Current.Dispatcher
,而不是Dispatcher.CurrentDispatcher
。后者只是在当前(后台(线程上启动一个新的Dispatcher,这不是您想要的。