13

文档说您可以通过使用Queue要调用的方法的属性来指定队列。这假设您总是希望在同一个队列上执行一个方法。是否有一种方法可以让进程调用Enqueue指定将作业放入的队列名称(有效地将决策权交给作业生成器,而不是作业的定义)。

4

3 回答 3

16

使用 IBackgroundJobClient 的实例,您可以指定一个队列。

IBackgroundJobClient hangFireClient = new BackgroundJobClient();
EnqueuedState myQueueState = new Hangfire.States.EnqueuedState("myQueue");
hangFireClient.Create<SomeClass>(c => c.SomeMethod(), myQueueState);

请注意,通过这种方式,重试会将作业放回默认队列。您将需要额外的代码才能使用 JobFilter 在同一个队列中重试

http://discuss.hangfire.io/t/one-queue-for-the-whole-farm-and-one-queue-by-server/490/3

于 2015-05-29T13:14:39.277 回答
2

因为对于 Hangfire 团队来说添加一个额外的参数似乎太难了 ;-)....

...我发现最方便的方法是创建两个只调用实际实现的方法,并[Queue]在每个方法上放置不同的属性。

通常,如果我需要在开发/生产之间切换队列,我只想调用类似RunOrder(...)的东西isTestOrder=boolean而不关心该级别的队列。

public void RunOrder(int orderId, bool isTestOrder) 
{
   if (isTestOrder) 
   {
      BackgroundJob.Enqueue(() => _RunTestOrder(orderId));
   } 
   else 
   {
      BackgroundJob.Enqueue(() => _RunOrder(orderId));
   }
}

[Queue("dev")]
public void _RunTestOrder(int orderId) {
  OrderProcessor.RunOrder(orderId); // actual code to call processor
}

[Queue("production")]`
public void _RunProductionOrder(int orderId) {
  OrderProcessor.RunOrder(orderId); // is the same in both 'hangfire proxies'
}

注意_用于指示这些并不意味着直接调用。我不记得hangfire方法是否需要公开-但如果确实需要公开,那么_更重要。

于 2019-02-03T22:58:40.430 回答
0

如果要动态更改队列,可以按照这种方式进行。

此实现适用于所有人EnqueueSchedule并且ContinueJobWith

诡计发生在[Queue("{0}")]. Hangfire 会将作业参数传递给给定的模式 ( "{0}"),String.Format("{0}", job.Args)以获取每次状态更改时的实际队列,因此即使重试也会应用目标队列。

突出显示的代码语法:

// Enqueue "MyBackgroundJob1" under "critical" queue
var job2 = BackgroundJob.Enqueue(() => MyBackgroundJob1("critical", 523));

// Use one of following Attributes depending on your hangfire version
//[AdvancedQueue("{0}")] //  1.6.X 
[Queue("{0}")] // In 1.7.X
public void MyBackgroundJob1(string queueName, int arg)
{
    // Job implementation
}

全面实施:

public class HangfireDynamicQueue
{
    public void EnqueJobs()
    {
        // Enqueue "MyBackgroundJob1" under "default" queue
        var job1 = BackgroundJob.Enqueue(() => MyBackgroundJob1("default", 123));

        // Enqueue "MyBackgroundJob1" under "critical" queue
        var job2 = BackgroundJob.Enqueue(() => MyBackgroundJob1("critical", 523));

        // Execute "MyBackgroundJob1" after 10 seconds under "delayed" queue
        var job3 = BackgroundJob.Schedule(() => MyBackgroundJob1("delayed", 678), TimeSpan.FromSeconds(10));

        // Run "MyBackgroundJob2" after job3 under "delayed" queue
        var job4 = BackgroundJob.ContinueJobWith(job3, () => MyBackgroundJob2("delayed", 435));
    }

    // Use one of following Attributes depending on your hangfire version
    //[AdvancedQueue("{0}")] //  1.6.X 
    [Queue("{0}")] // In 1.7.X
    public void MyBackgroundJob1(string queueName, int arg)
    {
        // Job implementation
    }

    // Use one of following Attributes depending on your hangfire version
    //[AdvancedQueue("{0}")] //  1.6.X 
    [Queue("{0}")] // In 1.7.X
    public void MyBackgroundJob2(string queueName, int arg)
    {
        // Job implementation
    }
}
于 2021-08-18T16:54:16.950 回答