Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Hangfire在作业中使用变量_C#_Asp.net Core_Hangfire - Fatal编程技术网

C# Hangfire在作业中使用变量

C# Hangfire在作业中使用变量,c#,asp.net-core,hangfire,C#,Asp.net Core,Hangfire,我知道hangfire和ASP.NET在不同的上下文中运行,它有自己的线程池,但我应该在后台作业中使用变量。这是可以理解的,因为事实上,这些作业可能不会在同一台服务器上运行。这意味着如果我执行\u locked=false(在Checker())中),它将永远不会被应用,因为它正在另一个上下文中运行。这对于BackgroundJob.Enqueue(()=>Start(bot))也是一样的,如果它是一个循环作业(cron作业),我在里面使用的那些变量将在每个cron作业弹出窗口中重置 在这种情况

我知道hangfire和ASP.NET在不同的上下文中运行,它有自己的线程池,但我应该在后台作业中使用变量。这是可以理解的,因为事实上,这些作业可能不会在同一台服务器上运行。这意味着如果我执行
\u 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;
}

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

如果运行单个实例,则:

1-使用静态变量:

public static bool _locked = false;

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

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

    services.AddSingleton<SomeClass>();

    //....
}
public void配置服务(IServiceCollection服务)
{
//....
services.AddSingleton();
//....
}
如果您在多个实例上运行此任务


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

您好,我认为当您调用函数时,\u loger函数是syn模式Async@LDS,上下文位于
\u locked
而不是
\u logger
。如果是这样,则将变量值传递给函数并在checker函数中检查,如time@LDS,其想法是在作业内部更改外部变量。不要检查它的值。@nop,为什么不将
\u lock
定义为静态变量,或者使用像Redis这样的快速数据库来更改
\u lock
变量谢谢您的回答!静态方法捕捉得很好。我不知道我怎么会错过了试一试。之前,我使用的是Redis实现,我确认它工作正常,因为它的缓存类似于EF的存储库。