【问题标题】:Hangfire use of variables inside jobsHangfire 在作业中使用变量
【发布时间】:2019-12-07 10:56:18
【问题描述】:

我知道hangfire 不会在与 ASP.NET 相同的上下文中运行,它有自己的线程池,但我应该在后台作业中使用变量。这是可以理解的,因为事实上,这些作业可能不会在同一台服务器上运行。这意味着如果我执行_locked = false;(在Checker() 中),它将永远不会被应用,因为它是在另一个上下文中运行的。 BackgroundJob.Enqueue(() => Start(bot)); 也是如此,如果它是一个重复的工作(cron 工作),我在里面使用的那些变量,总是会在每一个 cron 工作弹出时重置。

在这种情况下如何使用变量?

private UpdateSubscription _subscription;

private StringBuilder _sb = new StringBuilder();
private bool _locked = false;

public void RunStart(Bot bot)
{
    BackgroundJob.Enqueue(() => Start(bot));
}

public void Start(Bot bot)
{
    ApplyCredentialsOnClient();

    var lastKnownKline = _client.GetKlines(bot.CryptoPair.Symbol, bot.TimeInterval.Interval, limit: 2).Data.First();
    _subscription = _socketClient.SubscribeToKlineUpdates(bot.CryptoPair.Symbol, bot.TimeInterval.Interval, async data =>
    {
        if (data.Data.Final)
        {
            _logger.LogError($"Final | Open time: {data.Data.OpenTime.ToLocalTime()}");
        }

        if (lastKnownKline.OpenTime != data.Data.OpenTime)
        {
            // Static
            _logger.LogError($"Static | Open time: {lastKnownKline.OpenTime.ToLocalTime()} | {lastKnownKline.Close}");
        }
        else if (lastKnownKline.OpenTime == data.Data.OpenTime && lastKnownKline.Close != data.Data.Close)
        {
            // Real time
            if (!_locked)
            {
                _logger.LogError($"Real time | Open time: {data.Data.OpenTime.ToLocalTime()} | {data.Data.Close}");
                _locked = true;

                BackgroundJob.Schedule(() => Checker(), TimeSpan.FromMinutes(1));
            }
            else
            {
                _logger.LogInformation("Locked");
            }
        }

        lastKnownKline = data.Data.ToKline();
    }).Data;
}

public void Checker()
{
    _logger.LogWarning($"{DateTime.UtcNow.ToLocalTime()}");

    _locked = false;
}

【问题讨论】:

  • 您好,我认为当您调用函数异步时,_loger 函数是同步模式
  • @LDS,上下文落在_locked 而不是_logger
  • IF 所以将变量值传递给函数并像时间一样在检查器函数中进行检查
  • @LDS,这个想法是改变工作内部的外部变量。不检查它的价值。
  • @nop,为什么不将_lock定义为静态变量,或者使用Redis之类的快速数据库来更改_lock变量

标签: c# asp.net-core hangfire


【解决方案1】:

我想到了多种解决方案,我将从最简单的一个开始。

如果您运行的是单一实例,那么:

1-使用静态变量:

public static bool _locked = false;

或者

2-startup 中将整个类定义为Singleton,因此Hangfire 每次尝试激活该类时,都会到达同一个实例。

public void ConfigureServices(IServiceCollection services)
{
    //....

    services.AddSingleton<SomeClass>();

    //....
}

如果您在多个实例上运行此任务

然后您应该将此变量存储到Redis 之类的数据库中,并使用该数据库更改其状态。所以可以从多个作业中访问同一个变量。

【讨论】:

  • 感谢您的回答!使用静态方法很好。我不知道我怎么错过了尝试。早些时候,我使用的是 Redis 实现,我确认它工作正常,因为它的缓存类似于 EF 的存储库。
猜你喜欢
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多