问题描述
我有一个小的Dotnet核心程序(3.1.8),其中包含一些FileWatchers。 他们监视网络驱动器上的文件夹。 加载一些文件(此处最大为200-250个文件),程序意外崩溃。 这些文件是同时出现的,这要归功于Biztalk应用程序,它是由另一个服务器上的另一个进程移动的,我认为这里不重要,但我想提一提。
文件监视程序初始化:
private void InitializeInnerFilewatcher(List<string> filters)
{
_watcher = new FileSystemWatcher(WatchPath);
_watcher.InternalBufferSize = 65536;
if (filters.Count > 1)
{
_watcher.Filter = FILTER_ALL; // *.*
_customFilters = filters;
}
else
_watcher.Filter = filters.First();
_watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
_watcher.Changed += new FileSystemEventHandler(FileCreatedOrChanged);
_watcher.Created += new FileSystemEventHandler(FileCreatedOrChanged);
_watcher.Renamed += new RenamedEventHandler(FileRenamed);
_watcher.Error += Watcher_Error;
_watcher.EnableRaisingEvents = true;
}
在这里,我们有了filewatcher触发的每个事件的“过程”部分:
private void TryHandle(FileSystemEventArgs arg)
{
if (!File.Exists(arg.FullPath))
return;
if (!_customFilters.Any() || _customFilters.Any(x => PatternMatcher.MatchPattern(x,arg.Name)))
_memoryCache.AddOrGetExisting(arg.FullPath,arg,_cacheItemPolicy);
}
我试图避免对触发的文件系统事件进行任何实际处理,因此我将文件路径推送到memoryCache中,然后将其发送到ServiceBus队列以供任何使用者处理文件。
所有这些东西似乎在一整天都可以正常工作,没有高cpu,也没有高内存。我们已经在ApplicationInsights中记录了所有应用程序指标。
这是一次“真正的”崩溃,因此我们没有任何日志,只有事件查看器中的不良事件和转储文件。
事件查看器:
Faultinq module name: coreclr.dll,version: 470020.41105,time stamp: Ox5f3397ec
由于dotnet-dump,我们可以看到转储文件中捕获的错误:
> clrstack
OS Thread Id: 0xfd4c (27)
Child SP IP Call Site
00000022D55BE150 00007ffccc46789f [FaultingExceptionFrame: 00000022d55be150]
00000022D55BE650 00007FFC6D7A49D4 System.IO.FileSystemWatcher.ParseEventBufferAndNotifyForEach(Byte[]) [/_/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Win32.cs @ 249]
00000022D55BE6F0 00007FFC6D7A48E6 System.IO.FileSystemWatcher.ReadDirectoryChangesCallback(UInt32,UInt32,System.Threading.NativeOverlapped*) [/_/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Win32.cs @ 242]
00000022D55BE750 00007FFC6D6F189C System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object) [/_/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs @ 201]
00000022D55BE7C0 00007FFC6D7359B5 System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32,System.Threading.NativeOverlapped*) [/_/src/System.Private.CoreLib/src/System/Threading/Overlapped.cs @ 59]
00000022D55BE8F0 00007ffccc336ba3 [GCFrame: 00000022d55be8f0]
00000022D55BEAB0 00007ffccc336ba3 [DebuggerU2MCatchHandlerFrame: 00000022d55beab0]
> pe
Exception object: 000001e580001198
Exception type: System.ExecutionEngineException
Message: <none>
InnerException: <none>
StackTrace (generated):
<none>
StackTraceString: <none>
HResult: 80131506
如您所见,该错误似乎直接在Win32 API的FileSystemWatcher中发生。 我无法复制它,它仅在我们的生产环境中发生,因此无需告诉您我处于“紧急模式”。
WinDbg可能会更详细
解决方法
快速更新,因为我仍在解决它。
我创建了一个MS支持问题。 经过多次尝试,我们才成功复制了它。我们必须“玩”网络并模拟一些“干扰”。 似乎FileSystemWatcher事件未按应有的方式发送(它是通过TCP协议,SMB方式发送的)。 我们的团队仍在努力寻找可能的方法。
MS同意,无论是否存在真正的网络问题,这都不会以一些不安全的代码使FileSystemWatcher崩溃。 因此,他们只是做了PR来增加一些安全性。我仍在关注PR,但应该在.Net 5中进行修复,并在.Net Core 3.1(.9)中向后移植。
感谢您的帮助。
,此问题已在master (6.0)中修复,并反向移植到5.0和3.1。