Ray*_*yyz 7 c# winapi file-watcher .net-core
我有一个小的 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;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们有 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);
}
Run Code Online (Sandbox Code Playgroud)
我试图避免触发文件系统事件的任何实际过程,因此我将文件路径推送到 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, 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
Run Code Online (Sandbox Code Playgroud)
如您所见,该错误似乎直接发生在 Win32 API 中的 FileSystemWatcher 上。我无法重现它,它只发生在我们的生产环境中,因此无需告诉您我处于“紧急模式”。
WinDbg 可能更详细一点
只是一个快速更新,因为我仍在修复它的路上。
我创建了一个 MS 支持问题。经过多次尝试我们才成功重现它。我们必须“玩”网络并模拟一些“干扰”。看来 FileSystemWatcher 事件没有按应有的方式发送(它是通过 TCP 协议、SMB 方式发送的)。我们的团队仍在努力寻找它是如何发生的。
MS 同意,无论是否存在真正的网络问题,这都不应该在某些不安全的代码中使 FileSystemWatcher 崩溃。因此,他们只是做了一个PR来增加一些安全性。
我仍在关注 PR,但它应该在 .Net 5 中修复并在 .Net Core 3.1(.9) 中向后移植。
谢谢您的帮助。
| 归档时间: |
|
| 查看次数: |
677 次 |
| 最近记录: |