为什么FileSystemWatcher在Linux容器中无法监视Windows卷 [英] Why FileSystemWatcher doesn't work in Linux container watching Windows volume
问题描述
给出程序:
使用系统;使用System.IO;命名空间fsw_bug_poc{班级计划{私有静态FileSystemWatcher _fileSystemWatcher;静态void Main(string [] 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基础WORKDIR/app从mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS构建WORKDIR/srcCOPY ["fsw-bug-poc.csproj","]运行dotnet还原"fsw-bug-poc.csproj"复制 ..WORKDIR"/src/"RUN dotnet构建"fsw-bug-poc.csproj" -c版本-o/app从构建AS发布RUN dotnet发布"fsw-bug-poc.csproj" -c版本-o/app从基础AS决赛WORKDIR/appCOPY --from =发布/app.ENV DOTNET_USE_POLLING_FILE_WATCHER = true运行mkdir -p/app/观看音量/app/已观看ENTRYPOINT ["dotnet","fsw-bug-poc.dll"]
根据
修改共享卷文件夹中的文件:
什么都没发生!
有人可以解释发生了什么吗?FileSystemWatcher使用轮询策略,因此它应该以相同的方式工作,不是吗?
切换到 PhysicalFileProvider .Watch完成了这项工作.对于文件系统监视策略,这似乎是一种更可移植的实现.
PhysicalFileProvider
的当前实现支持 DOTNET_USE_POLLING_FILE_WATCHER
环境变量.我在 FileSystemWatcher
实现中找不到任何引用.
使用系统;使用System.IO;命名空间fsw_bug_poc{班级计划{私有静态PhysicalFileProvider _fileProvider;静态void Main(string [] args){_fileProvider =新的PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(),已监视")));WatchForFileChanges();Console.ReadKey(false);}私人无效WatchForFileChanges(){_fileChangeToken = _fileProvider.Watch("*.*");_fileChangeToken.RegisterChangeCallback(Notify,默认);}私有无效通知(对象状态){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 System;
using System.IO;
namespace fsw_bug_poc
{
class Program
{
private static PhysicalFileProvider _fileProvider;
static void Main(string[] args)
{
_fileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "Watched"));
WatchForFileChanges();
Console.ReadKey(false);
}
private void WatchForFileChanges()
{
_fileChangeToken = _fileProvider.Watch("*.*");
_fileChangeToken.RegisterChangeCallback(Notify, default);
}
private void Notify(object state)
{
Console.WriteLine("File change detected");
WatchForFileChanges();
}
}
}
这篇关于为什么FileSystemWatcher在Linux容器中无法监视Windows卷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!