Quartz.NET 3.0 似乎在同一范围内启动所有作业

2023-12-12

在定义了两个依赖于作用域服务 (ScopedDataAccess) 的作业(该服务是我的数据库上下文的包装器)之后,我很难将 Quartz 3.0.7 与 ASP.NET Core 2.2 一起使用:

services.AddScoped<IScopedDataAccess, ScopedDataAccess>();

services.AddDbContext<AggregatorContext>(opt => opt.UseSqlServer(configuration.GetConnectionString("Default")));

问题是两个作业接收相同的作用域服务实例(因此具有相同的数据库上下文),从而由于并行使用而导致上下文崩溃。

我的代码如下:

启动.cs

作业被定义为“范围”,我的期望是每个实例都在自己的“范围”中运行

private void ConfigureQuartz(IServiceCollection services, params Type[] jobs)
{
    services.AddSingleton<IJobFactory, QuartzJobFactory>();
    services.Add(jobs.Select(jobType => new ServiceDescriptor(jobType, jobType, ServiceLifetime.Scoped)));

    services.AddSingleton(provider =>
    {
        var schedulerFactory = new StdSchedulerFactory();
        var scheduler = schedulerFactory.GetScheduler().Result;

        scheduler.JobFactory = provider.GetService<IJobFactory>();
        scheduler.Start();
        return scheduler;
    });
}

protected void StartJobs(IApplicationBuilder app, IApplicationLifetime lifetime)
{
    var scheduler = app.ApplicationServices.GetService<IScheduler>();
    var configService = app.ApplicationServices.GetService<IConfigurationService>();

    QuartzServicesUtilities.StartJob<ArticleXUserDataRefresherJob>(scheduler, 
        TimeSpan.FromSeconds(configService.ArticleXUserDataRefresherJobPeriod));
    QuartzServicesUtilities.StartJob<LinkDataFetchJob>(scheduler,
        TimeSpan.FromSeconds(configService.LinkDataJobPeriod));

    lifetime.ApplicationStarted.Register(() => scheduler.Start());
    lifetime.ApplicationStopping.Register(() => scheduler.Shutdown());
}

Quartz服务实用程序

public class QuartzServicesUtilities
{
    public static void StartJob<TJob>(IScheduler scheduler, TimeSpan runInterval)
        where TJob : IJob
    {
        var jobName = typeof(TJob).FullName;

        var job = JobBuilder.Create<TJob>()
            .WithIdentity(jobName)
            .Build();

        var trigger = TriggerBuilder.Create()
            .WithIdentity($"{jobName}.trigger")
            .StartNow()
            .WithSimpleSchedule(scheduleBuilder =>
                scheduleBuilder
                    .WithInterval(runInterval)
                    .RepeatForever())
            .Build();

        scheduler.ScheduleJob(job, trigger);
    }
}

石英工作工厂

public class QuartzJobFactory : IJobFactory
{
    private readonly IServiceProvider _serviceProvider;

    public QuartzJobFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        var jobDetail = bundle.JobDetail;

        var job = (IJob)_serviceProvider.GetService(jobDetail.JobType);
        return job;
    }

    public void ReturnJob(IJob job) { }
}

有没有办法使用 Quartz.NET 为不同的作业获取不同的作用域?


据我所知,这对于 Quartz 来说是不可能的,我遇到了同样的问题,我找到的唯一解决方案是使用 ServiceLocator 并在作业中显式创建范围。

我以这样的方式结束:

// Pseudo-Code
public class MyJob : IJob
{
    private readonly IServiceLocator _serviceLocator;

    public MyJob(IServiceLocator serviceLocator)
    {
        _serviceLocator = serviceLocator;
    }

    public async Task Execute(JobExecutionContext context)
    {
        using(_serviceLocator.BeginScope())
        {
            var worker = _serviceLocator.GetService<MyWorker>();
            await worker.DoWorkAsync();
        }
    }
}

在这种情况下,您的工作人员仍然处于范围内,但工作不再存在。因此,您仍然可以在解决方案的其他地方使用您的 Worker,并且范围仍然有效。 您需要根据您使用的 DI 自行实现 ServiceLocatorIServiceLocator也必须由您定义。

Edit

在我们的一个项目中,我们使用这个:

/// <summary>
/// A simple service locator to hide the real IOC Container.
/// Lowers the anti-pattern of service locators a bit.
/// </summary>
public interface IServiceLocator
{
    /// <summary>
    /// Begins an new async scope.
    /// The scope should be disposed explicitly.
    /// </summary>
    /// <returns></returns>

    IDisposable BeginAsyncScope();
    /// <summary>
    /// Gets an instance of the given <typeparamref name="TService" />.
    /// </summary>
    /// <typeparam name="TService">Type of the requested service.</typeparam>
    /// <returns>The requested service instance.</returns>
    TService GetInstance<TService>() where TService : class;
}

我们主要使用 SimpleInjector 来实现此实现:

/// <summary>
/// SimpleInjector implementation of the service locator.
/// </summary>
public class ServiceLocator : IServiceLocator
{
    #region member vars

    /// <summary>
    /// The SimpleInjector container.
    /// </summary>
    private readonly Container _container;

    #endregion

    #region constructors and destructors

    public ServiceLocator(Container container)
    {
        _container = container;
    }

    #endregion

    #region explicit interfaces

    /// <inheritdoc />
    public IDisposable BeginAsyncScope()
    {
        return AsyncScopedLifestyle.BeginScope(_container);
    }

    /// <inheritdoc />
    public TService GetInstance<TService>()
        where TService : class
    {
        return _container.GetInstance<TService>();
    }
}

正如您所看到的,这只是一个简单的包装器,但有助于向消费者隐藏真正的 DI 框架。 我希望这有助于理解您所需的实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Quartz.NET 3.0 似乎在同一范围内启动所有作业 的相关文章

  • 什么可能导致 sock send() 命令上的“资源暂时不可用”

    什么会导致Resource temporarily unavailable套接字上的错误send 命令 套接字设置为AF UNIX SOCK STREAM 它在大多数情况下都有效 但偶尔会出现此错误 套接字的接收端似乎工作正常 我知道这不是
  • 预加载整个模型以估计 Tensorflow Serving 的内存消耗

    当执行预测时 Tensorflow Serving 延迟初始化模型 DAG 中的节点 这使得很难估计保存整个模型所需的内存 RAM 是否有一种标准方法可以强制 Tensorflow Serving 将模型完全初始化 加载到内存中 您可以使用
  • 使用和重载基类的模板成员函数?

    下面 构造Y超载X的成员函数f 两个重载都是模板函数 但采用不同的参数 typename and int 明确指定 struct X template
  • 共享库 C++ Makefile

    我需要编译胖二进制文件才能在另一台 Linux 机器上使用它 但缺少一些库 因此据我了解 我应该使用一些 shared 选项来编译它 但我不明白如何为此配置 Makefile 目前我的 makefile 如下所示 CC g CC FLAGS
  • 在 C 中使用模板函数的最短示例?

    我如何处理函数echo tpl可以采取1类型参数int or string 然后打印出来 C没有模板 我认为你能做的最好的事情就是使用联合或让函数具有不同的名称 后一种具有不同名称的方法是准标准方法 例如fabs fabsf fabsl a
  • C# 中的 memcpy 函数 [重复]

    这个问题在这里已经有答案了 可能的重复 C memcpy 等效项 https stackoverflow com questions 510971 c memcpy equivalent 相当于什么memcpyC 中的函数 正如已经说过的
  • 带和不带指针声明符的 C++11 自动声明

    不同类型有什么区别bar1 and bar2 int foo 10 auto bar1 foo auto bar2 foo If both bar1 and bar2 are int 编写指针声明符是否有意义 在里面bar2宣言 这些声明完
  • StreamReader 的默认值是多少?

    我需要使用这个构造函数public StreamReader Stream stream Encoding encoding bool detectEncodingFromByteOrderMarks int bufferSize bool
  • 如何为 IAsyncOperation 指定回调方法

    是否可以指定一个方法完成后调用async手术 平台 C Windows Phone 8 我需要实现非阻塞方法来异步发送UDP数据包 他们有我的方法 onWriteComplete int errorCode 操作完成时回调 这是我尝试过的
  • iText7 RegexBasedLocationExtractionStrategy 如何获取找到的文本的字体名和字体大小

    我尝试在 C 上使用 iText7 进行文本替换 我只能使用 RegexBasedLocationExtractionStrategy 获取搜索文本的内容和矩形 并且我想获取文本的字体和大小 有什么建议么 谢谢 你可以实施IText提取策略
  • Linux 相当于 GetCommandLine 和 CommandLineToArgv?

    我想知道是否有一些 API 可以在 Linux 上获取当前进程的命令行参数 我想我是非常不清楚的 该问题的真正目的是通过命令行参数传递 unicode 文件名 从文件中读取 proc self cmdline 例如 wallyk zf od
  • 来自“void *”的dynamic_cast

    根据this https stackoverflow com questions 3155277 cannot dynamic cast void to templated class void 没有 RTTI 信息 因此从void 不合法
  • 我不明白这个霍夫曼算法的实现

    template
  • 对双向链表进行排序 C++

    尝试通过遍历列表的循环来完成此操作 在循环中 我将头节点输入到我定义的排序函数中 然后使用 strcmp 来确定节点中的哪个名称是否应该排在前面 它不起作用 因为写得太早了 我通过一次沿着列表一个节点进行线性比较 而不是回去查看第一个节点是
  • 检测非 DPI 感知应用程序是否已扩展/虚拟化

    我正在尝试在 WinForms 应用程序中检测它是否由于操作系统具有高 DPI 而以缩放 虚拟化模式启动 目前 在以 3840x2400 缩放 200 缩放运行的系统中 应用程序将分辨率视为 1920x1200 DPI 为 96 缩放因子为
  • C# 中的任意精度小数?

    是否存在任意精度decimal类可用于 C 吗 我见过几个任意精度整数类 但这并不完全相同 您可以使用 J 库java math BigDecimal类 如果已安装 只需添加一个引用即可vjslib me remembers one of
  • 运行 SQL Server 报告服务时如何解决“远程服务器返回错误:(401) 未经授权”?

    我正在用这个code http www codeproject com Articles 25994 Creating a Proxy to Download PDF Reports from SRS从 SSRS 创建和下载 PDF 报告
  • 着色器可以旋转形状以面向相机吗?

    我制作了一个球出现在 3D 空间中的场景 三角球耗费大量资源 所以我使用带有球纹理的二维表面 四边形 来完成此操作 但现在我需要在每次相机移动时调整形状的方向 我使用位置变换和 LookAt 方法来完成此操作 问题是我可以优化这个吗 如果可
  • C++ 中的 golang 风格“延迟”[重复]

    这个问题在这里已经有答案了 我正在阅读有关 go 语言的defer http blog golang org defer panic and recover陈述 它允许您指定函数结束时要执行的操作 例如 如果您有一个文件指针或资源 则只需指
  • 将用户控件绑定到 bool 属性的相反值

    非常简单 我想做同样的事情this https stackoverflow com questions 534575 how do i invert booleantovisibilityconverter但在winforms中 谷歌似乎提

随机推荐

  • 适用于 xamarin android 的 ClearableEdittext

    我已访问此链接和堆栈上的许多其他链接 但我无法找到 xamarin android 的类似解决方案 https stackoverflow com a 14470930 7462031 我已经实现了框架布局解决方案 但我希望在整个应用程序中
  • Android 上的简单地图应用程序(google api v2)。不起作用。错误

    我尝试在 Android 上编写一个简单的地图应用程序 但唯一的结果是错误 我尝试按照应有的方式对其进行编程 但它仍然不起作用 主要活动 package com example guidebook import android os Bun
  • 这个说法正确吗? HTTP GET 方法始终没有消息正文

    这个说法正确吗 HTTP GET 方法始终没有消息正文 我没有找到 RFC2616 的任何部分明确说明这一点 如果这不是真的 那么在什么情况下 Http GET 请求会包含消息正文 Neither 休息客户端 nor 休息控制台支持这一点
  • 在 WPF 中保存单击按钮的用户颜色设置

    我在保存按钮的某些属性时遇到了一些问题 按钮很小并且有多种颜色 当我按下一个按钮时 一些指定的颜色正在改变 我想保存它们以供下次启动 我可以保存文本框值 但这 我不能 Code public MainWindow InitializeCom
  • 使用 Ruby 捕获网络摄像头图像[重复]

    这个问题在这里已经有答案了 Ruby 中有没有可以用来捕获网络摄像头图像的库 必须在 GNU Linux 上运行 这看起来不错http www wedesoft demon co uk hornetseye api files Hornet
  • 测试时如何将模拟对象注入到类中?

    我的用户类别如下 public class UserResource Inject UserService userService public boolean createUser User user DbResponse res use
  • 在 R 中使用 React JS 抓取网页

    我正在尝试抓取下面的页面 https metro zakaz ua uk promotion 1 此页面包含反应内容 我可以用代码抓取第一页 url https metro zakaz ua uk promotion 1 read html
  • NASM 在 .text 部分声明变量

    我刚刚开始使用 nasm 学习 asm 我注意到如果我在 text 部分声明一个变量 我的代码工作得很好 只是想知道为什么我可以这样做以及它与使用 data 部分有何不同 我还注意到在 bss 部分中的变量名称后面需要一个 但在 data
  • BIRT 变量 - 如何创建和使用?

    我需要创建一个全局报告变量来获取第一个表的变量 然后在最后一个表中使用它来进行计算 我是 BIRT 新手 没有找到相关指南 有人可以解释我该怎么做吗 我们在大纲视图的 变量 部分初始化一个全局报告变量 然后我们可以从报告的任何位置设置和获取
  • 网页更新无需轮询

    我正在开发一个网络应用程序 用户可以在其中请求服务 并且提供商将可以响应他 因此 当用户请求某种服务时 我们的应用程序将向提供商发送通知 要求他响应用户 我想做的是 当用户请求服务时 提供商会立即收到通知 就像 Facebook 那样 实现
  • 按外键求和分组

    我需要对表 B 中的数量进行求和 并根据创建日期时间的 id 进行分组 并与表 A 的 id 连接 CREATE TABLE TableA Id int Name varchar 50 Type varchar 10 ForeignKeyI
  • 未定义的符号:clapack_sgesv

    我有这个小代码 from numpy import from scipy import signal misc import matplotlib pyplot as plt path pics band 1 misc imread pat
  • 基于 Woocommerce 中的用户角色和付款方式的百分比折扣

    我试图为functions php 编写一个代码片段 当同时选择角色 订阅者 和付款方式 信用卡 时 该代码片段会对购物车总额应用2 的折扣 到目前为止我的进展 function discount when role and payment
  • 从 HTML 中抓取 pdf 文件

    如何从 HTML 中抓取 pdf 文档 我正在使用 R 只能从 HTML 中提取文本 我要抓取的网站示例如下 https www bot or th English MonetaryPolicy Northern EconomicRepor
  • Internet Explorer 中的 element.dataset

    我需要一种方法来列出data 元素的属性 我会用Object keys element dataset 但IE 9 0没有dataset支持 我应该如何以适用于 IE 9 0 以及 Chrome Firefox Safari 的方式执行此操
  • 将随机数添加到脚本标签

    我想向动态构造的脚本标记添加一个随机数 下面的代码不会向生成的脚本标签添加任何随机数 有人知道如何添加随机数吗 var wss document createElement script wss nonce random string ws
  • ClearCase SCM 适配器支持注释

    我想用版本历史注释一些代码 当使用 SVN 时 这在 Eclipse 中很容易 但 Rational ClearCase SCM Adapter 插件似乎不支持它 我快速 Google 搜索显示 ClearCase 在命令行上支持通过以下方
  • Node.js - 如何检查 http 请求中 URL 的状态

    我正在尝试运行一个简单的应用程序 使用 http 服务器模块检查 URL 的状态 基本上这是一个简单的 http 服务器 require http createServer function req res res writeHead 20
  • Perl 中的 chomp 未按预期工作

    我在 Perl 中发现了 chomp 的奇怪行为 我无法理解为什么 chomp 会这样工作 以下行无法按预期工作 if chomp str1 eq chomp str2 但是 以下工作正常 chomp str1 chomp str2 if
  • Quartz.NET 3.0 似乎在同一范围内启动所有作业

    在定义了两个依赖于作用域服务 ScopedDataAccess 的作业 该服务是我的数据库上下文的包装器 之后 我很难将 Quartz 3 0 7 与 ASP NET Core 2 2 一起使用 services AddScoped