该文档说您可以通过使用Queue
要调用的方法的属性来指定队列。这假设您总是希望在同一个队列上执行一个方法。是否有一种方法可以让进程调用Enqueue
指定将作业放入的队列名称(有效地将决策权交给作业生成器,而不是作业的定义)。
3 回答
使用 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
因为对于 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方法是否需要公开-但如果确实需要公开,那么_
更重要。
如果要动态更改队列,可以按照这种方式进行。
此实现适用于所有人Enqueue
,Schedule
并且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
}
}