首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CancellationToken + Hangfire

CancellationToken + Hangfire
EN

Stack Overflow用户
提问于 2019-12-31 02:57:19
回答 1查看 2.7K关注 0票数 5

首先,我决定使用Hangfire,因为它可以在不同的Windows服务中运行代码,或者实际上可以在不同的服务器上运行代码。我可以使用Task类轻松地执行我的任务,但是我的逻辑将在很长一段时间内24/7运行,直到它被用户停止为止,而且我认为任务无法处理。所以我才用汉弗莱。我对不同的解决方案持开放态度。更具体地说,我的逻辑是使用web套接字24/7监控东西。

如果您看下面的代码,它有一个运行方法,它在来自Hangfire的BackgroundJob中生成了一个新的机器人。问题是,当我不得不停止一个特定的机器人(比方说“机器人1")时,它应该以某种方式识别它目前没有的机器人。

Hangfire的文档是不完整的,或者至少我不明白如何从所写的文档中做到这一点。https://docs.hangfire.io/en/latest/background-methods/using-cancellation-tokens.html

代码语言:javascript
复制
private UpdateSubscription _subscription;
private readonly CancellationTokenSource _cts = new CancellationTokenSource();

public async Task RunAsync(string botName)
{
    var jobId = BackgroundJob.Enqueue(() => StartAsync(botName, _cts.Token));
    await _cache.SetAsync($"bot_{botName.Replace(" ", "_")}", jobId);
}

public void Start(Bot bot, CancellationToken token)
{
    // heavy logic
    _subscription = _socketClient.SubscribeToKlineUpdates(bot.CryptoPair.Symbol, bot.TimeInterval.Interval /*KlineInterval.OneHour*/, async data =>
    {
        ... logic ...

        if (token.IsCancellationRequested)
        {
            await _socketClient.Unsubscribe(_subscription);
        }
    }
}

public async Task StopAsync(string botName)
{
    var jobId = await _cache.GetAsync<string>($"bot_{botName.Replace(" ", "_")}");

    if (jobId == null)
        return;

    BackgroundJob.Delete(jobId);
}

编辑: BackgroundJob正在以字符串的形式返回jobId,但是即使在BackgroundJob.Delete(jobId)调用之后,if (token.IsCancellationRequested)也不会被触发。

我还使用Redis来存储作业id。也编辑了上面的代码。

EN

回答 1

Stack Overflow用户

发布于 2021-11-25 07:06:18

要取消Hangfire作业,您不必提供自己的CancellationToken。相反,您提供给Hangfire的排队方法需要一个该类型的参数。当通过代码对作业进行查询时,在这种情况下,默认的CancellationToken.None和Hangfire会注意在执行方法时提供真正的令牌。在您的方法中,您可以常规地询问令牌的状态,如果需要的话退出。

若要取消正在运行的作业,Hangfire本身监视两个事件以触发所提供的令牌。服务器要么获得关闭请求(这将使作业进入新的排队状态,以便在下次启动时再次运行),要么获得作业删除请求。

下面是一些代码草图:

代码语言:javascript
复制
// The method initiated from Hangfire Worker with special parameters
// for cancellationToken and context, filled by Hangfire.
public async Task MyJob(int someParameter, CancellationToken cancellationToken, PerformContext context)
{
    for (int i = 0; i < 100; i++)
    {
        cancellationToken.ThrowIfCancellationRequested();
        Console.WriteLine($"Processing {i} in job {context.Job.Id}");
        await DoSomething(i, cancellationToken);
    }
}

private string EnqueueMyJob(int someParameter)
{
    // When enqueuing a job, just provide some default values for the *magic parameters*
    return jobClient.Enqueue<MyTaskClass>(task => task.MyJob(someParameter, CancellationToken.None, null));
}

private void CancelMyJob(string jobId)
{
    // If the job is currently running, the cancellation token will be set.
    jobClient.Delete(jobId);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59539078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档