C# Filewatcher队列管理
我有一个filewatcher,它正在监视目录中的文件更改。 发生这种情况时,每个文件都在一个由FileProcessor类(带有线程)管理的队列中排队。 我想在表格1中更新Q中文件的数量(每次更新该数量时) 我尝试了几件事,包括:C# Filewatcher队列管理,c#,C#,我有一个filewatcher,它正在监视目录中的文件更改。 发生这种情况时,每个文件都在一个由FileProcessor类(带有线程)管理的队列中排队。 我想在表格1中更新Q中文件的数量(每次更新该数量时) 我尝试了几件事,包括: class FileProcessor : IDisposable { private static Form1 frm; 以及稍后在课堂上的调用: frm.Invoke((MethodInvoker)delegate { frm.button4.Text
class FileProcessor : IDisposable
{
private static Form1 frm;
以及稍后在课堂上的调用:
frm.Invoke((MethodInvoker)delegate { frm.button4.Text = Qcounte(); });
我有一个System.NullReferenceException,因为我不知道如何在frm中声明Form1:(
下面是带有更新标签的函数的主窗体:SetQ(字符串s)
在FileProcessor类中,以下是我调用标签更新的方式:
Form1.deldisplayQ.Invoke(Qcounte());
public string Qcounte()
{
return Convert.ToString(fileNamesQueue.Count);
}
Form1.deldisplayQ.Invoke(Qcounte());
下面是全班同学:
class FileProcessor : IDisposable
{
private EventWaitHandle eventWaitHandle = new AutoResetEvent(false);
private Thread worker;
private readonly object locker = new object();
private Queue<string> fileNamesQueue = new Queue<string>();
public static Form1 frm ;
public FileProcessor()
{
worker = new Thread(Work);
worker.Start();
}
public void EnqueueFileName(string FileName)
{
lock (locker) fileNamesQueue.Enqueue(FileName);
eventWaitHandle.Set();
}
private void Work()
{
while (true)
{
string fileName = null;
lock (locker)
if (fileNamesQueue.Count > 0)
{
if (fileName == null) return;
}
if (fileName != null)
{
ProcessFile(fileName);
}
else
{
eventWaitHandle.WaitOne();
}
}
}
private void ProcessFile(string FileName)
{
Globals.getTags(FileName);
Globals.ecritDb(FileName);
}
public string Qcounte()
{
return Convert.ToString(fileNamesQueue.Count);
}
#region IDisposable Members
public void Dispose()
{
EnqueueFileName(null);
worker.Join();
eventWaitHandle.Close();
}
#endregion
}
类文件处理器:IDisposable
{
private EventWaitHandle EventWaitHandle=new AutoResetEvent(false);
私人线程工作者;
私有只读对象锁定器=新对象();
专用队列fileNamesQueue=新队列();
公共静态表格1 frm;
公共文件处理器()
{
工人=新线程(工作);
worker.Start();
}
public void排队文件名(字符串文件名)
{
lock(locker)fileNamesQueue.Enqueue(FileName);
eventWaitHandle.Set();
}
私人工作()
{
while(true)
{
字符串文件名=null;
锁(储物柜)
如果(fileNamesQueue.Count>0)
{
如果(fileName==null)返回;
}
如果(文件名!=null)
{
进程文件(文件名);
}
其他的
{
eventWaitHandle.WaitOne();
}
}
}
私有void进程文件(字符串文件名)
{
getTags(文件名);
Globals.ecritDb(文件名);
}
公共字符串Qcounte()
{
返回Convert.ToString(fileNamesQueue.Count);
}
#区域IDisposable成员
公共空间处置()
{
排队文件名(空);
worker.Join();
eventWaitHandle.Close();
}
#端区
}
我的问题是:
在哪里触发FileProcessor类中的排队和出列,以便在我的主窗体中看到文件处理的增加和减少?
提前感谢在我看来,代码并不完整,但以下是您应该做的一些事情:
public static Form1 instance{get;set;}
添加到Form1类中。在表单的构造函数中设置它
public partial class Form1 : Form
{
public static Form1 Instance { get; set; }
public Form1()
{
InitializeComponent();
Instance = this;
}
public void UpdateText(string text)
{
BeginInvoke( new Action( () =>
{
button4.Text = text;
}));
}
BeginInvoke()
这很重要,因为FileProcessor运行在不同的线程上,无法更改任何UI控件
private void ProcessFile(string FileName)
{
Globals.getTags(FileName);
Globals.ecritDb(FileName);
//update UI
Form1.Instance.UpdateText("hello");
}
当然,我们可以在这里使用接口或抽象,而不是直接访问表单,但有时简单就足够了。哇,谢谢!当我通过公共void UpdateText(字符串文本)时,我有一个例外:无法将lambda表达式转换为“Delegate”类型,因为它不是委托类型。我修改了UpdateText方法,复制它,然后重试。是的,通过阅读您提供的链接,我发现了这一点…谢谢,委托工作得很好(谢谢),队列管理不好(或者太快)。我将调查队列是否存在事件。
private void ProcessFile(string FileName)
{
Globals.getTags(FileName);
Globals.ecritDb(FileName);
//update UI
Form1.Instance.UpdateText("hello");
}