为什么 FileSystemWatcher 在 Linux 容器中不起作用,用于监视 Windows 卷 [英] Why FileSystemWatcher doesn't work in Linux container watching Windows volume

查看:46
本文介绍了为什么 FileSystemWatcher 在 Linux 容器中不起作用,用于监视 Windows 卷的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定程序:

使用系统;使用 System.IO;命名空间 fsw_bug_poc{课程计划{私有静态 FileSystemWatcher _fileSystemWatcher;静态无效主(字符串 [] args){_fileSystemWatcher = new FileSystemWatcher("Watched", "*.*");_fileSystemWatcher.Changed += 通知;_fileSystemWatcher.Created += 通知;_fileSystemWatcher.Deleted += 通知;_fileSystemWatcher.Renamed += 通知;_fileSystemWatcher.IncludeSubdirectories = true;_fileSystemWatcher.EnableRaisingEvents = true;Console.ReadKey(false);}私有静态无效通知(对象发送者,FileSystemEventArgs e){Console.WriteLine($"{e.FullPath} {e.ChangeType}");}}}

Dockerfile:

FROM mcr.microsoft.com/dotnet/core/runtime:2.2-stretch-slim AS base工作目录/应用程序从 mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build工作目录/src复制 ["fsw-bug-poc.csproj", ""]运行 dotnet 还原fsw-bug-poc.csproj"复制 ..工作目录/src/"运行 dotnet build "fsw-bug-poc.csproj" -c Release -o/app从构建 AS 发布运行 dotnet 发布 "fsw-bug-poc.csproj" -c Release -o/appFROM base AS final工作目录/应用程序复制 --from=publish/app .ENV DOTNET_USE_POLLING_FILE_WATCHER=true运行 mkdir -p/app/Watched音量/应用程序/观看入口点 ["dotnet", "fsw-bug-poc.dll"]

根据

修改共享卷文件夹中的文件:

什么都没发生!!

谁能解释一下这是怎么回事?FileSystemWatcher 正在使用轮询策略,所以它应该以相同的方式工作,不是吗?

解决方案

切换到 PhysicalFileProvider.Watch 完成了这项工作.对于文件系统监视策略来说,它似乎是一种更可移植的实现.

PhysicalFileProvider 的当前实现支持 DOTNET_USE_POLLING_FILE_WATCHER 环境变量.我在 FileSystemWatcher 实现中找不到它的任何参考.

使用 Microsoft.Extensions.FileProviders;使用 Microsoft.Extensions.Primitives;使用系统;使用 System.IO;命名空间 fsw_bug_poc{课程计划{私有静态 PhysicalFileProvider _fileProvider;私有静态 IChangeToken _fileChangeToken;静态无效主(字符串 [] args){_fileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "."));WatchForFileChanges();Console.ReadKey(false);}私有静态无效 WatchForFileChanges(){_fileChangeToken = _fileProvider.Watch(*.*");_fileChangeToken.RegisterChangeCallback(Notify, default);}私有静态无效通知(对象状态){Console.WriteLine(检测到文件更改");WatchForFileChanges();}}}

Given the program:

using System;
using System.IO;

namespace fsw_bug_poc
{
    class Program
    {
        private static FileSystemWatcher _fileSystemWatcher;

        static void Main(string[] args)
        {
            _fileSystemWatcher = new FileSystemWatcher("Watched", "*.*");
            _fileSystemWatcher.Changed += Notify;
            _fileSystemWatcher.Created += Notify;
            _fileSystemWatcher.Deleted += Notify;
            _fileSystemWatcher.Renamed += Notify;
            _fileSystemWatcher.IncludeSubdirectories = true;
            _fileSystemWatcher.EnableRaisingEvents = true;

            Console.ReadKey(false);
        }

        private static void Notify(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine($"{e.FullPath} {e.ChangeType}");
        }
    }
}

The Dockerfile:

FROM mcr.microsoft.com/dotnet/core/runtime:2.2-stretch-slim AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["fsw-bug-poc.csproj", ""]
RUN dotnet restore "fsw-bug-poc.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "fsw-bug-poc.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "fsw-bug-poc.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
RUN mkdir -p /app/Watched
VOLUME /app/Watched
ENTRYPOINT ["dotnet", "fsw-bug-poc.dll"]

According to this link adding ENV DOTNET_USE_POLLING_FILE_WATCHER=true to the Dockerfile fixes the FileSystemWatcher not working inside the container.

Even with this fix, FileSystemWatcher will not work when running a Linux container on Windows and mounting a shared driver to a volume:

docker build -t fsw-bug-poc .
docker run -it --rm -v C:Shared:/app/Watched fsw-bug-poc

Modifying a file inside the container:

Modifying files in the shared volume folder:

Nothing happens!!

Can someone explain what is going on? The FileSystemWatcher is using a polling strategy, so it should work the same way, shouldn't it?

解决方案

Switching to PhysicalFileProvider.Watch did the job. It seems to be a more portable implementation for file system watching strategies.

The current implementation of PhysicalFileProvider supports the DOTNET_USE_POLLING_FILE_WATCHER environment variable. I couldn't find any reference of it in FileSystemWatcher implementation.

using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Primitives;
using System;
using System.IO;

namespace fsw_bug_poc
{
    class Program
    {
        private static PhysicalFileProvider _fileProvider;
        private static IChangeToken _fileChangeToken;

        static void Main(string[] args)
        {
            _fileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "."));
            WatchForFileChanges();

            Console.ReadKey(false);
        }

        private static void WatchForFileChanges()
        {
            _fileChangeToken = _fileProvider.Watch("*.*");
            _fileChangeToken.RegisterChangeCallback(Notify, default);
        }

        private static void Notify(object state)
        {
            Console.WriteLine("File change detected");
            WatchForFileChanges();
        }
    }
}

这篇关于为什么 FileSystemWatcher 在 Linux 容器中不起作用,用于监视 Windows 卷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆