C# FileSystemWatcher行为不一致

C# FileSystemWatcher行为不一致,c#,winforms,filesystemwatcher,C#,Winforms,Filesystemwatcher,我已经在设计器中设置了所有FSW属性(EnableRaisingEvents=true,filter=*.tif,IncludeSubdirectories=true,path=bla\bla\bla) 该应用程序在Windows Server 2008 R2标准计算机上运行,并监视本地文件夹中创建的文件。我使用计算机网络名“格雷厄姆”,而不是“C:\” 问题是,当文件被创建/移动到监视目录时,FSW并不总是触发。看起来有时候是这样,但大多数时候不是这样 在调试和查看我的机器上的文件夹时,也会出

我已经在设计器中设置了所有FSW属性(EnableRaisingEvents=true,filter=*.tif,IncludeSubdirectories=true,path=bla\bla\bla)

该应用程序在Windows Server 2008 R2标准计算机上运行,并监视本地文件夹中创建的文件。我使用计算机网络名“格雷厄姆”,而不是“C:\”

问题是,当文件被创建/移动到监视目录时,FSW并不总是触发。看起来有时候是这样,但大多数时候不是这样

在调试和查看我的机器上的文件夹时,也会出现一些奇怪的行为。如果我远程控制服务器机器并将文件移动到监视的文件夹,则不会发生任何事情。但如果我将文件从共享网络文件夹移动到监视的文件夹中,FSW每次都会触发

这使得我很难找到错误/bug。有人有什么想法吗

这就是所有的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Ekonomikompetens_unikt_namn
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
        {
            StringBuilder log = new StringBuilder();

            try
            {
                log.Append("--------------------").AppendLine().Append(DateTime.Now).AppendLine().Append("--------------------").AppendLine();

                FileInfo file = new FileInfo(e.FullPath);

                while (IsFileLocked(file))
                {
                    System.Threading.Thread.Sleep(300);
                }
                string oFile = e.FullPath;
                string nFile = oFile.Insert(oFile.Length - 4, "_" + DateTime.Now.ToString().Replace(" ", "").Replace("-", "").Replace(":", "")).Replace("\\XML Konvertering", "").Replace(@"\\GRAHAM\AnyDoc Invoices", @"\\FAKTURASERVER\AnyDoc");

                if (!Directory.Exists(nFile.Substring(0, nFile.LastIndexOf('\\'))))
                {
                    Directory.CreateDirectory(nFile.Substring(0, nFile.LastIndexOf('\\')));
                    File.Move(oFile, nFile);
                    Directory.Delete(oFile.Substring(0, oFile.LastIndexOf('\\')));
                }
                else
                {
                    File.Move(oFile, nFile);
                }

                log.Append("* Moved and stamped file: ").AppendLine().Append(oFile).Append(" to ").Append(nFile).AppendLine().Append("--------------------").AppendLine();

            }
            catch (Exception x)
            {
                log.AppendLine().Append("*** ERROR *** ").Append(x).AppendLine().AppendLine();
            }
            finally
            {
                TextWriter tw = new StreamWriter(@"C:\tidslog\log.txt", true, Encoding.Default);
                //TextWriter tw = new StreamWriter(@"C:\PROJEKT\tidsstämplarn\log.txt", true, Encoding.Default);
                tw.Write(log);
                tw.Dispose();
            }
        }

        protected virtual bool IsFileLocked(FileInfo file)
        {
            FileStream stream = null;
            try
            {
                stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
            }
            catch (IOException)
            {
                return true;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }
            return false;
        }
    }
}
注意:try-catch-finally可能做得不太好,但我对编码还不太熟悉,也不确定如何“捕获”这些东西,尽管记录器从未记录过错误。由于FSW从不开火,因此不会发生错误。我猜。

订阅活动并检查错误(如果有)


如果正在创建或更改大量文件,请执行此操作

1>增加

医生说:

增加缓冲区的大小可以防止丢失文件系统 改变事件。但是,增加缓冲区大小是昂贵的,因为 它来自无法交换到磁盘的非分页内存,因此 使缓冲区尽可能小。要避免缓冲区溢出,请使用 NotifyFilter和IncludeSubdirectories属性用于筛选 不需要的更改通知


2>另外,您在创建的
fileSystemWatcher1\u中做了很多事情,这可能会导致缓冲区溢出,导致它错过一些事件…请改用线程池。

我很好奇:虽然“创建”方法尚未完成,但不会检测到新创建的文件?我以为他们会排队?@Anirudh所以,理论上,即使我马上把它放到一个线程中,我也可能错过一个填充,对吗?如果您喜欢多个客户同时将文件放入一个位置。我猜您必须设置多个文件观察程序,并将检测到的文件操作排队(以及过滤双重或过程)@derape oops..我错了..我刚刚测试了它,即使你执行了线程,它也会引发事件。睡眠1分钟。但是缓冲区可能会溢出,一些事件可能会丢失missed@Anirudh感谢您的澄清,我想默认缓冲区对于大多数情况来说已经足够了。也许我会在我还有时间的时候检查有多少文件操作会导致filewatcher丢失文件…我不认为缓冲区大小是一个问题,一次只有一个文件。该文件是一个单独的图像,用当前时间“标记”并移动到另一个文件夹。当它工作时,操作会根据@Anirudh的回答接受一些注释:因为,您的事件处理程序代码正在忙于执行,可能是您的文件没有被注意到。你应该做的是提出建议,使用线程池,然后,_fileWatcher.Created+=(sender,e)=>YourOwnHandler(e.FullPath);对于这些“监视文件夹中可能被锁定的新文件并将其移动到其他地方”任务,我总是不使用
FileSystemWatcher
,而是使用计时器定期扫描文件夹(例如每秒一次),收集文件名,然后尝试移动它们。当您不必与
FileSystemWatcher
@christopherén:Read my exception series:的特性搏斗时,解决方案会变得更简单、更可靠。也许它可以帮助您更好地理解异常。