如何将Quartz定时任务Job的返回值传递给.NET MVC控制器
实现方案
方案1:依赖注入+单例共享服务(推荐,ASP.NET Core场景)
这个方案耦合度低、线程安全,适合现代.NET项目:
- 首先定义用于存储最新TransacID的共享服务接口与实现:
public interface ITransacIdStore { int LatestTransacId { get; set; } } public class TransacIdStore : ITransacIdStore { private int _latestId; // 保证线程安全读写 public int LatestTransacId { get => Interlocked.CompareExchange(ref _latestId, 0, 0); set => Interlocked.Exchange(ref _latestId, value); } }
- 在Program.cs/Startup.cs中将服务注册为单例:
builder.Services.AddSingleton<ITransacIdStore, TransacIdStore>(); // 注册Quartz服务,使用容器创建Job builder.Services.AddQuartz(q => { q.UseMicrosoftDependencyInjectionJobFactory(); }); builder.Services.AddQuartzHostedService(opt => { opt.WaitForJobsToComplete = true; });
- 修改Job代码,将获取到的TransacID写入共享服务:
public class Incompletescanjob : IJob { private readonly TransactionDAL _transactionContext = new TransactionDAL(); private readonly ITransacIdStore _idStore; // 注入共享服务 public Incompletescanjob(ITransacIdStore idStore) { _idStore = idStore; } public Task Execute(IJobExecutionContext context) { Console.WriteLine("--> Database check completed"); // 优化:只查一次库 var incompleteRecord = _transactionContext.CheckIncompleteExists(); var transacId = incompleteRecord != null ? incompleteRecord.TransacID : 0; // 写入共享存储 _idStore.LatestTransacId = transacId; return Task.CompletedTask; } }
- 在HomeController中注入服务直接读取即可:
public class HomeController : Controller { private readonly ITransacIdStore _idStore; public HomeController(ITransacIdStore idStore) { _idStore = idStore; } public IActionResult SomeAction() { var currentId = _idStore.LatestTransacId; // 后续业务逻辑 return Ok(); } }
方案2:静态变量存储(适用于传统.NET Framework场景)
如果没有依赖注入环境,可以直接用静态全局变量存储,注意加锁保证线程安全:
- 定义全局静态存储类:
public static class SharedData { private static int _latestTransacId; private static readonly object _lockObj = new object(); public static int LatestTransacId { get { lock(_lockObj) return _latestTransacId; } set { lock(_lockObj) _latestTransacId = value; } } }
- Job执行时直接赋值:
SharedData.LatestTransacId = transacId; - 控制器内直接读取:
var id = SharedData.LatestTransacId;
注意事项
- 原Job中
CheckIncompleteExists被调用了两次,建议优化为单次查询存储结果,避免重复数据库查询开销 - 若需要控制器实时感知ID更新,可以在共享服务中添加事件委托,ID更新时触发事件通知订阅的控制器逻辑
内容的提问来源于stack exchange,提问作者somethingfishy
相关产品推荐
相关产品推荐

