我正在开发一个计划的作业,以使用Quartz.net将消息发送到消息队列。IJob的Execute方法不是异步的。所以我不能使用异步任务。但是我想用await关键字调用一个方法。
请在下面找到我的代码。不知道我做的是否正确。谁能帮我这个忙吗?
private async Task PublishToQueue(ChangeDetected changeDetected)
{
_logProvider.Info("Publish to Queue started");
try
{
await _busControl.Publish(changeDetected);
_logProvider.Info($"ChangeDetected message published to RabbitMq. Message");
}
catch (Exception ex)
{
_logProvider.Error("Error publishing message to queue: ", ex);
throw;
}
}
public class ChangedNotificatonJob : IJob
{
public void Execute(IJobExecutionContext context)
{
//Publish message to queue
Policy
.Handle<Exception>()
.RetryAsync(3, (exception, count) =>
{
//Do something for each retry
})
.ExecuteAsync(async () =>
{
await PublishToQueue(message);
});
}
}
这是正确的方法吗?我用过.GetAwaiter();
Policy
.Handle<Exception>()
.RetryAsync(_configReader.RetryLimit, (exception, count) =>
{
//Do something for each retry
})
.ExecuteAsync(async () =>
{
await PublishToQueue(message);
}).GetAwaiter()
Polly.ExecuteAsync()
返回Task
。使用any Task
,您可以仅调用.Wait()
它(或其他阻止方法)来同步阻止,直到它完成或引发异常。
如您所见,既然IJob.Execute(...)
不是async
,就不能使用await
,因此,如果您想发现成功或以其他方式在IJob.Execute(...)
返回之前进行发布,则别无选择,只能同步阻止任务。
.Wait()
将导致任务中的任何异常被重新抛出,并包装在中AggregateException
。如果所有由Polly精心安排的重试均失败,则会发生这种情况。
您需要决定如何处理该异常:
如果您希望调用者处理它,则将其重新抛出或不捕获它,并使其在Quartz作业之外进行级联。
如果您想在返回前处理它IJob.Execute(...)
,则需要一个try {} catch {}
整体.ExecuteAsync(...).Wait()
。或考虑Polly的.ExecuteAndCaptureAsync(...)
语法:通过将执行的最终结果放入PolicyResult
实例中,可以避免提供外部try-catch的麻烦。参见Polly doco。
如果您的唯一目的是在消息发布失败的地方进行日志记录,并且您不在乎该日志记录是否发生在IJob.Execute(...)
返回之前,则还有另一种选择。在这种情况下,.Wait()
您可以将延续任务链接到ExecuteAsync()
using上,而不是using .ContinueWith(...)
,并在那里处理任何登录。我们采用这种方法,并且将失败的消息发布捕获到特殊的“消息医院”中-捕获足够的信息,以便我们可以选择是否稍后再重新发布该消息(如果适用)。这种方法是否有价值,取决于对您永不丢失信息的重要性。
编辑:GetAwaiter()
是无关紧要的。它不会神奇地让您开始await
在非async
方法内部使用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句