移除SingletonAttribute后Azure WebJob无法获取单例锁问题咨询
我来帮你搞定这个本地运行WebJob时的单例锁问题,这个坑我之前也踩过,给你几个靠谱的解决方案:
清理本地锁文件
WebJobs SDK在本地运行时,默认会把单例锁存储在文件系统里,路径一般是%LOCALAPPDATA%\Temp\jobsingleton。如果之前的WebJob进程没有正常退出,锁文件可能残留导致后续启动无法获取锁。你可以直接删除这个目录下的所有文件,然后重启WebJob试试。显式禁用单例行为
即使你移除了SingletonAttribute,WebJobs SDK对TimeTrigger函数默认还是会启用单例监听器来防止重复触发。你可以在JobHost的配置里直接禁用单例锁:
如果你用的是较旧的WebJobs SDK(2.x及以下):var config = new JobHostConfiguration(); // 禁用监听器锁和函数执行锁 config.Singleton.ListenerLockPeriod = TimeSpan.Zero; config.Singleton.LockPeriod = TimeSpan.Zero; var host = new JobHost(config); host.RunAndBlock();如果你用的是Azure.WebJobs 3.x+(依赖注入模式):
var builder = new HostBuilder(); builder.ConfigureWebJobs(b => { b.AddTimers(); }); builder.Services.Configure<SingletonOptions>(options => { options.ListenerLockPeriod = TimeSpan.Zero; options.LockPeriod = TimeSpan.Zero; }); var host = builder.Build(); using (host) { await host.RunAsync(); }调整TimeTrigger的监控设置
本地开发时,可以给TimeTrigger加上UseMonitor = false参数,禁用触发器的监控机制,这样就不会依赖单例锁来控制触发了(注意这个只适合本地开发,生产环境建议保留监控):[TimeTrigger("0 */5 * * * *", UseMonitor = false)] public async Task MyFunctionAsync(TextWriter log) { // 你的函数逻辑 }清理开发环境缓存
有时候Visual Studio的调试进程残留、项目的bin/obj目录缓存也会导致奇怪的锁问题。你可以关闭VS,删除项目下的bin和obj文件夹,重新生成项目后再运行WebJob。
为啥移除SingletonAttribute后问题还存在?
这是因为WebJobs SDK对TimeTrigger类型的函数,默认会自动启用单例监听器,目的是防止多个WebJob实例同时执行同一个定时任务。本地运行时,如果之前的进程异常退出,锁文件没有被正确释放,就会出现后续启动无法获取锁的情况,哪怕你没加SingletonAttribute也会触发这个问题。
内容的提问来源于stack exchange,提问作者D. Siemer

