C# filesystemwatcher在Linux上停止响应

C# filesystemwatcher在Linux上停止响应,c#,linux,filesystemwatcher,C#,Linux,Filesystemwatcher,我有一个filesystemwatcher(C#.net Core 2.2),它在Windows上可靠运行,但在Linux上运行几个小时后,相同的代码就会停止工作。我正在监视一个本地目录(和子目录)。受监视的目录位于我的应用程序所在的同一Linux服务器上(不是网络共享) 我创建了一个测试应用程序,它每X秒创建一次测试文件,并监视事件。它将运行3-5个小时,然后事件停止触发,没有错误 我已将测试应用程序配置为每5秒运行一次,并允许它运行30分钟而不会出现问题。然后我将延迟时间间隔增加到30秒、1

我有一个filesystemwatcher(C#.net Core 2.2),它在Windows上可靠运行,但在Linux上运行几个小时后,相同的代码就会停止工作。我正在监视一个本地目录(和子目录)。受监视的目录位于我的应用程序所在的同一Linux服务器上(不是网络共享)

我创建了一个测试应用程序,它每X秒创建一次测试文件,并监视事件。它将运行3-5个小时,然后事件停止触发,没有错误

我已将测试应用程序配置为每5秒运行一次,并允许它运行30分钟而不会出现问题。然后我将延迟时间间隔增加到30秒、10分钟、30分钟,一切似乎都正常。但是,当我将间隔增加到每小时一个文件时,我在3-5小时后开始看到问题

我尝试将max_user_watchers增加到100000,将max_user_实例增加到256,但我并不认为这是问题所在。不过,这也没用

public bool CreateWatcher()
{
    bool isStarted = false;

    try
    {
        // Set criteria for files to watch
        watcher.Filter = watcherFilter;

        // folder(s) to watch
        watcher.Path = watcherPath;

        // Watch in subfolders
        watcher.IncludeSubdirectories = includeSubdirectories;

        // Add event handlers
        switch (watcherEventType)
        {
            case EventType.Created:
                watcher.Created += new FileSystemEventHandler(OnCreated);
                break;
            case EventType.Deleted:
                watcher.Deleted += new FileSystemEventHandler(OnDeleted);
                break;
            case EventType.Changed:
                watcher.Changed += new FileSystemEventHandler(OnChanged);
                break;
            default:
                break;
        }

        // Set error event handler
        watcher.Error += new ErrorEventHandler(OnError);

        // Start watching
        watcher.EnableRaisingEvents = true;
        isStarted = true;

        _Log.Information("Watching path {watcherPath} for new files of type {watcherFilter}", watcherPath, watcherFilter);

    }
    catch (Exception ex)
    {
        _Log.Error("CreateWatcher: {@ex}", ex);
        if (watcher != null)
        {
            watcher.EnableRaisingEvents = false;
            watcher.Dispose();
        }
    }
    return isStarted;
}

public void StartWatcher()
{
    try
    {
        // Ensure watched path exists
        if (!Directory.Exists(watcherPath))
        {
            _Log.Warning("Watcher path {watcherPath} does not exist.  Attempting to create.", watcherPath);

            try
            {
                // Attempt to create watcherPath
                Directory.CreateDirectory(watcherPath);
                _Log.Information("Created watcherPath: {watcherpath}", watcherPath);
            }
            catch (Exception ex)
            {
                _Log.Error("StartWatcher : Error creating watcherPath: {@ex}", ex);
            }
        }

        CreateWatcher();
    }
    catch (Exception ex)
    {
        _Log.Error("StartWatcher : {@ex}", ex);
    }
}


private void OnError(object source, ErrorEventArgs e)
{
    try
    {
        // If Buffer overflow
        if (e.GetException().GetType() == typeof(InternalBufferOverflowException))
        {
            // Too many events -- some of the file system events are being lost.
            // Nothing we can do about it so log the error and continue...
            _Log.Error("OnError : {@exception}", e.GetException());
            return;
        }

        //-----------------------------------------------------
        // If not buffer overflow must be a folder access issue
        //-----------------------------------------------------
        _Log.Error("OnError Error: Watched directory not accessible");

        // Stop raising events
        watcher.EnableRaisingEvents = false;

        // Dispose of current watcher
        watcher.Dispose();

        int counter = 0;
        Boolean isStarted = false;

        // continue to loop if path does not exist or watcher cannot start 
        while (isStarted == false && counter < retryAttempts)
        {
            try
            {
                // If watcher path exists
                if (Directory.Exists(watcherPath))
                {
                    _Log.Information("Folder Access Restored: {watcherPath}", watcherPath);

                    // Attempt to recreate watcher
                    isStarted = CreateWatcher();
                }

                // Path does not exist
                else
                {
                    _Log.Error("OnError Folder Inaccesible {watcherPath}", watcherPath);
                }
            }
            catch (Exception ex)
            {
                _Log.Error("OnError Error restarting filesystemwatcher {@ex}", ex);
            }

            // wait a little and try again
            System.Threading.Thread.Sleep(retryTimeOut);
            counter++;
        }
        // If not restarted, kill service
        if (!isStarted)
        {
            _Log.Error("OnError Exceeded the maximum number of attempts to reconnect to watcher path.  Resolve path issue and restart Relay");
            return;
        }
    }
    catch (Exception ex)
    {
        _Log.Error("OnError Error attempting to recover file system watcher: {@ex}", ex);
    }
}
public bool CreateWatcher()
{
bool-isStarted=false;
尝试
{
//设置要监视的文件的条件
watcher.Filter=watcherFilter;
//要监视的文件夹
watcher.Path=watcherPath;
//在子文件夹中监视
watcher.IncludeSubdirectories=IncludeSubdirectories;
//添加事件处理程序
开关(watcherEventType)
{
案例事件类型。已创建:
watcher.Created+=新文件系统EventHandler(onCreate);
打破
案例事件类型。已删除:
watcher.Deleted+=新文件系统EventHandler(OnDeleted);
打破
案例事件类型。已更改:
watcher.Changed+=新文件系统EventHandler(OnChanged);
打破
违约:
打破
}
//设置错误事件处理程序
watcher.Error+=新的ErrorEventHandler(OnError);
//开始看
watcher.EnableRaisingEvents=true;
IsStart=true;
_Log.Information(“为类型为{watcherFilter}的新文件监视路径{watcherPath}”,watcherPath,watcherFilter);
}
捕获(例外情况除外)
{
_错误(“CreateWatcher:{@ex}”,ex);
如果(观察者!=null)
{
watcher.EnableRaisingEvents=false;
watcher.Dispose();
}
}
返回开始;
}
公共无效StartWatcher()
{
尝试
{
//确保监视路径存在
如果(!Directory.Exists(watcherPath))
{
_警告(“观察者路径{watcherPath}不存在。正在尝试创建。”,watcherPath);
尝试
{
//尝试创建watcherPath
CreateDirectory(watcherPath);
_Log.Information(“创建的watcherPath:{watcherPath}”,watcherPath);
}
捕获(例外情况除外)
{
_Error(“StartWatcher:Error创建watcherPath:{@ex}”,ex);
}
}
CreateWatcher();
}
捕获(例外情况除外)
{
_Log.Error(“StartWatcher:{@ex}”,ex);
}
}
私有void OnError(对象源,ErrorEventArgs e)
{
尝试
{
//如果缓冲区溢出
if(e.GetException().GetType()==typeof(InternalBufferOverflowException))
{
//事件太多--某些文件系统事件正在丢失。
//对此我们无能为力,所以请记录错误并继续。。。
_错误(“OnError:{@exception}”,e.GetException());
返回;
}
//-----------------------------------------------------
//如果不是,缓冲区溢出必须是文件夹访问问题
//-----------------------------------------------------
_Log.Error(“OnError错误:监视的目录不可访问”);
//停止举办活动
watcher.EnableRaisingEvents=false;
//处理当前监视程序
watcher.Dispose();
int计数器=0;
布尔值isStarted=false;
//如果路径不存在或观察程序无法启动,则继续循环
while(isStarted==false&&counter
假设测试仪在每5秒运行一次时可以处理大量文件,但在每小时间隔一个文件时仅处理几个文件时失败,我认为这不是资源问题

当我自动创建测试文件时,我只需增加文件名(例如:1.xml、2.xml、3.xml),就可以在磁盘上看到正在创建的文件。当进程工作时,在日志中,我看到创建文件的命令,然后在看到watcher事件触发后立即执行。但是,几个小时后,我看到了创建