asp.net - FileSystemWatcher 不会在 Azure 中触发
问题描述
我试图找出为什么我的 FileSystemWatcher 在本地工作,但当我将它部署到 Azure webapp 时却没有。
我验证了文件是在 webapp 文件夹中创建的,但是在创建文件时,观察者似乎没有触发。Azure 日志或我的应用程序日志中没有相关的错误/警告消息。我创建了一个示例应用程序进行调查,我在那里看到了同样的问题。
public sealed class TestController : Controller
{
private static readonly ILog _log = LogManager.GetLogger(typeof(TestController));
private static readonly string _folder = ConfigurationManager.AppSettings["BasePath"];
private static FileSystemWatcher _watcher;
[HttpGet, Route("start-monitoring")]
public ActionResult StartMonitoring()
{
if (_watcher != null)
return new HttpStatusCodeResult(HttpStatusCode.OK);
_watcher = new FileSystemWatcher(_folder, "*.*") { EnableRaisingEvents = true };
_watcher.Created += (sender, args) =>
_log.Debug($"YAY!!! Watcher triggered, new file found `{args.FullPath}`");
_log.Debug($"Watcher started for folder `{_folder}`");
return new HttpStatusCodeResult(HttpStatusCode.Created);
}
[HttpGet, Route("create-file/{filename}")]
public async Task<ActionResult> CreateFileAsync(string filename)
{
string fullFilename = $"{_folder}\\{filename}.txt";
using (var writer = new StreamWriter(fullFilename))
{
await writer.WriteAsync("Some content").ConfigureAwait(false);
}
_log.Debug($"Created file `{fullFilename}`");
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
}
本地
使用上面的代码,当我转到 时http://localhost:23481/start-monitoring
,这将创建FileSystemWatcher
监视文件夹的C:\test
文件夹。
然后,当我转到http://localhost:23481/create-file/blahblah
一个名为blahblah.txt
gets created in folder 的文件时C:\test
。日志文件显示正在创建的文件,以及 FSW 触发器表示它注意到出现了一个新文件。
2019-08-15T10:37:54.705Z DEBUG TestProject.TestController
Watcher started for folder `C:\test`
2019-08-15T10:38:02.399Z DEBUG TestProject.TestController
Created file `C:\test\blahblah.txt`
2019-08-15T10:38:02.400Z DEBUG TestProject.TestController
YAY!!! Watcher triggered, new file found `C:\test\blahblah.txt`
2019-08-15T10:38:06.137Z DEBUG TestProject.TestController
Created file `C:\test\another.txt`
2019-08-15T10:38:06.141Z DEBUG TestProject.TestController
YAY!!! Watcher triggered, new file found `C:\test\another.txt`
天蓝色
我将相同的代码部署到 Azure,唯一的代码区别是配置中的基本路径。日志显示FileSystemWatcher
已正确创建以监视D:\home\site\wwwroot\test
Azure webapp 文件系统上的文件夹。
然后,当我转到https://xxx.azurewebsites.net/create-file/blahblah
一个名为blahblah.txt
gets created in folder 的文件时D:\home\site\wwwroot\test
。日志文件显示正在创建的文件,但不显示创建时触发的 FSW:
2019-08-15T10:43:01.681Z DEBUG TestProject.TestController
Watcher started for folder `D:\home\site\wwwroot\test`
2019-08-15T10:43:27.010Z DEBUG TestProject.TestController
Created file `D:\home\site\wwwroot\test\blahblah.txt`
2019-08-15T10:43:33.834Z DEBUG TestProject.TestController
Created file `D:\home\site\wwwroot\test\another.txt`
我也尝试在文件夹中手动创建一个文件,但这仍然不会触发 YAY !!! 日志条目。FileSystemWatcher 不会在 Azure 中触发是一个已知问题,还是我错过了什么?
编辑
我已经为 FileSystemWatcher 支持的所有事件分配了处理程序,即 Changed/Created/Deleted/Disposed/Error/Renamed,在 Azure 中唯一为我触发的是Changed
. 我想我必须做一些黑客行为来监控 Changed 事件,我可以假设如果文件存在,它是一个“Created”事件,否则是一个“Deleted”事件。
解决方案
我更改了我的代码以侦听FileSystemWatcher
. 我发现在 Azure 上触发的唯一事件就是Changed
事件。不会调用其他事件。我找不到任何关于此的文档,所以它可能是一个错误,也可能是设计的,谁知道呢。
我现在使用的修复如下,基本上是在 Changed 事件上,我检查文件是否存在,如果存在,我假设它是“文件创建事件”,否则是“文件删除事件”。
[HttpGet, Route("start-monitoring")]
public ActionResult StartMonitoring()
{
if (_watcher != null)
return new HttpStatusCodeResult(HttpStatusCode.OK);
_watcher = new FileSystemWatcher(_folder, "*.*") { EnableRaisingEvents = true };
//none of these events are triggered in Azure
_watcher.Created += (sender, args) =>
_log.Debug($"Watcher triggered `Created`, `{args.FullPath}`");
_watcher.Deleted += (sender, args) =>
_log.Debug($"Watcher triggered `Deleted`, `{args.FullPath}`");
_watcher.Renamed += (sender, args) =>
_log.Debug($"Watcher triggered `Renamed`, `{args.OldFullPath}` to `{args.FullPath}`");
_watcher.Error += (sender, args) =>
_log.Debug($"Watcher triggered `Error`, `{args.GetException().ToString()}`");
_watcher.Disposed += (sender, args) =>
_log.Debug($"Watcher triggered `Disposed`");
//Changed is the only event that gets triggered in Azure
_watcher.Changed += (sender, args) =>
{
if (System.IO.File.Exists(args.FullPath))
_log.Debug($"Watcher triggered `Changed (created)`, `{args.FullPath}`");
else
_log.Debug($"Watcher triggered `Changed (deleted)`, `{args.FullPath}`");
};
_log.Debug($"Watcher started for folder `{_folder}`");
return new HttpStatusCodeResult(HttpStatusCode.Created);
}
现在这对我来说似乎很好用:
2019-08-16T08:54:37.419Z DEBUG TestProject.TestController
Watcher started for folder `C:\test`
2019-08-16T08:55:16.625Z DEBUG TestProject.TestController
Created file `C:\test\moo.txt`
2019-08-16T08:55:16.634Z DEBUG TestProject.TestController
Watcher triggered `Changed (created)`, `C:\test\moo.txt`
2019-08-16T08:55:50.096Z DEBUG TestProject.TestController
Created file `C:\test\poop.txt`
2019-08-16T08:55:50.101Z DEBUG TestProject.TestController
Watcher triggered `Changed (created)`, `C:\test\poop.txt`
推荐阅读
- php - 在 Laravel 中,它采用数据库中不可用的不同表行 ID
- bash - 如何在 bash 中设置动态地形计划?
- acumatica - 以编程方式创建时,销售订单中的税额未更新
- junit - (Junit5) 如何防止@BeforeEach 中的@AfterTest?
- c# - 如何克服以下错误:System.IO.IOException:'目录名称无效。在我的 foreach 循环中?
- python - 如果相关矩阵的值超出python中的阈值,如何在相关矩阵中获取行列对?
- ios - 调用 PKAddPaymentPassRequest 处理程序后失败
- python - Python 函数运行后部分刷新或清除 Jupyter 单元格显示
- ios - 将 UIView 转换为 UIImage 会导致大视图崩溃
- java - 实现计数出现方法的Listnode问题(递归)