使用FileSystemWatcher来触发事件,然后删除新创建的文件?
我有一个Windows服务使用FileSystemWatcher监视文件夹,打印添加的图像,然后在打印后删除图像。使用FileSystemWatcher来触发事件,然后删除新创建的文件?
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
FileSystemWatcher Watcher = new FileSystemWatcher();
Watcher.Path = @"C:\Images";
Watcher.Created += new FileSystemEventHandler(Watcher_Changed);
Watcher.EnableRaisingEvents = true;
}
private void Watcher_Changed(object sender, FileSystemEventArgs e)
{
try
{
PrintDocument myDoc = new PrintDocument();
myDoc.PrintPage += new PrintPageEventHandler(print);
FilePath = e.FullPath;
myDoc.PrinterSettings.PrinterName = @"\\Network Printer";
myDoc.Print();
using (StreamWriter sw = new StreamWriter("C:\\error.txt"))
{
sw.WriteLine("Printed File: " + FilePath);
}
File.Delete(e.FullPath);
}
catch(Exception excep)
{
using (StreamWriter sw = new StreamWriter("C:\\error.txt"))
{
sw.WriteLine("Error: " + excep.ToString());
}
}
}
的问题是,我得到抛出Error: System.IO.IOException: The process cannot access the file because it is being used by another process.
不同的是该文件正在由另一个进程使用,当我尝试将其删除。我猜这是因为FileSystemWatcher保留了一些对它的引用。任何想法在这里做什么,打印后删除文件?
编辑:
private void print(object sender, PrintPageEventArgs e)
{
try
{
using (Image i = Image.FromFile(FilePath))
{
Point p = new Point(0, 0);
e.Graphics.DrawImage(i, p);
}
}
catch(Exception exep)
{
throw exep;
}
}
我申请使用块建议,这个功能太,也感动了删除这一功能是事件处理程序: 之前没有从我的代码包含此功能mydoc.EndPrint,以确保与文件的所有关系都被切断,这似乎是个窍门。
void myDoc_EndPrint(object sender, PrintEventArgs e)
{
File.Delete(FilePath);
}
的PrintDocument实现IDisposable,你需要确保它释放它的文件句柄通过在使用块包装它。
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
FileSystemWatcher Watcher = new FileSystemWatcher();
Watcher.Path = @"C:\Images";
Watcher.Created += new FileSystemEventHandler(Watcher_Changed);
Watcher.EnableRaisingEvents = true;
}
private void Watcher_Changed(object sender, FileSystemEventArgs e)
{
try
{
using (PrintDocument myDoc = new PrintDocument())
{
myDoc.PrintPage += new PrintPageEventHandler(print);
FilePath = e.FullPath;
myDoc.PrinterSettings.PrinterName = @"\\Network Printer";
myDoc.Print();
using (StreamWriter sw = new StreamWriter("C:\\error.txt"))
{
sw.WriteLine("Printed File: " + FilePath);
}
}
File.Delete(e.FullPath);
}
catch(Exception excep)
{
using (StreamWriter sw = new StreamWriter("C:\\error.txt"))
{
sw.WriteLine("Error: " + excep.ToString());
}
}
}
没有这个运气。同样的错误。 '错误:System.IO.IOException:进程无法访问文件'C:\ ProcessBookImages \ 013Figure.GIF',因为它正在被另一个进程使用。' – xdumaine 2010-09-29 20:31:26
我想那么它一定是监视器本身。我认为FileSystem观察器持有对文件的引用,因为Changed事件在Created事件之前触发。尝试将代码移至Created事件。 – 2010-09-29 20:37:47
不,据此 - http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.created.aspx - 我最后的评论是不正确的。 – 2010-09-29 20:40:29
杀mydoc,我认为这是保持在文件中使用
默认情况下,FSW触发多个事件正在创建的文件,同时,不只是当文件被插入到文件系统。为了尽量减少这种影响我设置:
FSW.NotifyFilter = NotifyFilters.FileName;
另外,FSW时将触发第一个创建的文件,而不是当它已经完全加载到文件系统这一事件。如果你有一个大文件,那么在这个事件触发和实际可用的文件之间会有明显的时间延迟。甚至没有FSW告诉你文件被完全写入的时间。为了解决这个问题,我使用了一个重试循环来打开该文件,以独占阅读并用try/catch捕获错误。并继续尝试加载文件,直到我成功(或者我达到了重试限制),并在失败时睡一会儿。
如果谷歌了一下周围,你会发现很多的解决方案的周边FSW限制
的问题是不是与FileSystemWatcher
获得。它与Image.FromFile(FilePath)
。该静态方法行为非常糟糕,即使将其置于下一个垃圾收集之后,也会在文件上留下锁定。在您的打印方法试试这个来获取图像:
Image.FromStream(new MemoryStream(File.ReadAllBytes(FilePath)))
使用['FileMon'(http://technet.microsoft.com/en-us/sysinternals/bb896642.aspx),看看哪些进程正在锁定文件。 – Oded 2010-09-29 19:57:13