在 HangFire 中,我可以使用队列名称入队而不是使用队列属性吗?
In HangFire, can I Enqueue with a queue name instead of using the Queue attribute?
这个documentation说你可以通过在要调用的方法上使用Queue
属性来指定一个队列。这假设您总是希望在同一个队列上执行一个方法。有没有办法让调用 Enqueue
的进程指定将作业放入的队列名称(有效地将决策权交给作业生成器,而不是作业的定义)。
使用 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]
属性。
通常,如果我需要在开发/生产之间切换队列,我只想用 isTestOrder=boolean
调用 RunOrder(...)
之类的东西,而不用担心那个级别的队列。
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 方法是否需要 public,但如果确实需要,那么 _
更重要。
如果你想改变队列动态你可以按照这种方式。
此实现适用于所有 Enqueue
、Schedule
和 ContinueJobWith
技巧发生在 [Queue("{0}")]
。 Hangfire 将使用 String.Format("{0}", job.Args)
将作业参数传递给给定模式 ("{0}"
),以便在 每次状态更改 时获取实际队列,因此将应用目标队列 即使重试.
突出显示的代码语法:
// 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
}
}
这个documentation说你可以通过在要调用的方法上使用Queue
属性来指定一个队列。这假设您总是希望在同一个队列上执行一个方法。有没有办法让调用 Enqueue
的进程指定将作业放入的队列名称(有效地将决策权交给作业生成器,而不是作业的定义)。
使用 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]
属性。
通常,如果我需要在开发/生产之间切换队列,我只想用 isTestOrder=boolean
调用 RunOrder(...)
之类的东西,而不用担心那个级别的队列。
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 方法是否需要 public,但如果确实需要,那么 _
更重要。
如果你想改变队列动态你可以按照这种方式。
此实现适用于所有 Enqueue
、Schedule
和 ContinueJobWith
技巧发生在 [Queue("{0}")]
。 Hangfire 将使用 String.Format("{0}", job.Args)
将作业参数传递给给定模式 ("{0}"
),以便在 每次状态更改 时获取实际队列,因此将应用目标队列 即使重试.
突出显示的代码语法:
// 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
}
}