作业中对变量的篝火使用

问题描述 投票:2回答:1

我知道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;
}
c# asp.net-core hangfire
1个回答
1
投票

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

如果您在一台服务器上运行,则:

1-使用静态变量:

public static bool _locked = false;

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

public void ConfigureServices(IServiceCollection services)
        {
            ....
            services.AddSingleton<SomeClass>();
            ....
        }

并且如果您正在多个节点上运行此任务,则>>

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

© www.soinside.com 2019 - 2024. All rights reserved.