

























今天在 ASP.NET Web Site Project 中集成 Hangfire 并实现图片/视频压缩后台任务,遇到了一系列技术挑战,最终全部解决。下面是关键问题与解决方法的总结:
/hangfire 返回 404现象:访问 /hangfire 时出现 404,Startup.cs 的 Configuration 方法断点未命中。
原因:Web Site Project 中 OWIN 自动发现机制不可靠,且 Global.asax 中 Application_Start 未正确配置。
解决:
放弃 OWIN 自动发现,改用 Global.asax 的 Application_Start 手动配置 Hangfire 存储并启动 BackgroundJobServer。
删除 App_Code 下多余的 Global.asax,只保留根目录下的 Global.asax。
在 web.config 中添加 <add key="owin:AutomaticAppStartup" value="false" /> 禁用 OWIN 自动发现。
Current JobStorage instance has not been initialized yet现象:创建 BackgroundJobServer 时抛出此异常。
原因:未在 BackgroundJobServer 之前调用 GlobalConfiguration.Configuration.UseSqlServerStorage。
解决:确保在 Application_Start 中先配置存储,后启动服务器。
Application_Start 未执行,日志未生成现象:Global.asax 中的 Application_Start 没有输出日志。
原因:IIS 应用程序池未设置为 AlwaysRunning,或网站未预加载。
解决:
设置应用程序池:启动模式 = AlwaysRunning,闲置超时 = 0。
设置网站:预加载已启用 = True。
Enqueued 状态不执行现象:数据库 HangFire.Job 表中有任务但状态一直是 Enqueued。
原因:BackgroundJobServer 未成功启动或被 IIS 回收。
解决:通过上述 IIS 配置保证服务器常驻,同时在 Application_Start 中正确启动服务器。
Unable to load library 'libSkiaSharp'现象:压缩图片时抛出 DllNotFoundException。
原因:SkiaSharp 依赖原生库 libSkiaSharp.dll,Web Site Project 不会自动将其复制到 bin 目录。
解决:
安装 SkiaSharp.NativeAssets.Win32(或 Win64)NuGet 包。
手动从包目录(~/.nuget/packages/skiasharp.nativeassets.win32/版本号/runtimes/win-{x86|x64}/native/)找到 libSkiaSharp.dll。
将其复制到网站的 bin 目录下。
确保应用程序池位数与 DLL 位数匹配。
HttpContext.Current 在后台任务中为 null,导致日志写入失败现象:WriteLog 方法中使用 HttpContext.Current.Request.PhysicalApplicationPath 引发“请求在此上下文中不可用”。
原因:Hangfire 后台任务执行时没有 HTTP 上下文。
解决:将 WriteLog 中的路径获取改为 AppDomain.CurrentDomain.BaseDirectory 或 HostingEnvironment.ApplicationPhysicalPath。
现象:3.76MB 视频压成了 5.76MB,画质下降。
原因:使用了 -preset veryfast 导致压缩效率低,且原始视频可能已高度压缩,重新编码时反而膨胀。
解决:
改用 -preset medium 或 -preset slow 获得更好压缩率。
调整 -crf 值(如 23 → 28)增大压缩力度。
可选添加 -vf scale=1280:-2 降低分辨率。
现象:压缩完成后无法删除原文件或移动临时文件,提示文件被占用。
原因:使用的 FFmpeg 为共享版(--enable-shared),依赖多个 DLL,进程退出后文件句柄未及时释放。
解决:
换用静态编译版 FFmpeg(从 gyan.dev 下载),只需一个 ffmpeg.exe。
在代码中添加 Thread.Sleep(100) 和文件操作重试循环。
使用 Process 时正确等待退出、关闭进程、异步读取错误流。
现象:服务器上 FFmpeg 路径问题。
解决:
推荐将静态版 ffmpeg.exe 放在网站 bin 目录下,代码中使用绝对路径或 AppDomain.CurrentDomain.BaseDirectory + "bin/ffmpeg.exe"。
或者设置系统环境变量,但 IIS 可能无法继承,不如直接指定路径可靠。
连接字符串:统一在 web.config 的 <connectionStrings> 中配置,供 Hangfire 和业务代码共用。
日志系统:改造 WriteLog 使其不依赖 HttpContext,并在 App_Data 或指定目录输出。
Hangfire Dashboard:虽然 Web Site Project 中 OWIN 启动困难,但最终通过 Global.asax 手动启动服务器,Dashboard 仍可访问(需正确配置 OWIN 启动类或使用第三方方案,用户最终放弃 Dashboard,改用数据库查询和自定义日志监控)。
任务重试:Hangfire 默认自动重试,可通过 [AutomaticRetry] 特性调整。
✅ Hangfire 后台任务稳定运行,任务不再卡在 Enqueued。
✅ 图片压缩功能正常,原生库正确加载。
✅ 视频压缩功能正常,参数优化后体积合理,文件操作不再报错。
✅ 日志系统健壮,不依赖 HTTP 上下文。
✅ IIS 配置优化,应用程序池始终运行,后台任务不因空闲而停止。
Web Site Project 对 OWIN 支持不友好,尽量使用 Global.asax 手动启动 Hangfire。
SkiaSharp 需要手动部署原生库,不能仅依赖 NuGet 自动复制。
FFmpeg 优先使用静态编译版,避免 DLL 依赖和文件锁定问题。
后台任务中避免使用 HttpContext.Current,改用 AppDomain 或 HostingEnvironment。
IIS 必须配置为 AlwaysRunning + 预加载,否则后台服务会被回收。
文件操作要添加重试和延时,以应对进程释放句柄的延迟。
今天的问题虽然曲折,但最终全部攻克。如果以后遇到类似需求,可以快速参考这套方案。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。