我有一个场景,我正在安排一个BackgroundJob在应用程序启动后的一些随机秒后运行。执行作业后,我再次安排相同的BackgroundJob在一些随机秒后运行,然后继续运行并且永不停止。
我想要的是如果在这个连续过程中Hangfire发生任何异常,我想关闭我的asp.net核心应用程序。
例如,当这个过程发生时,我停止了SQL Server。所以hangfire给出了这个明显的异常
System.Data.SqlClient.SqlException:建立与SQL Server的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确,以及SQL Server是否配置为允许远程连接。 (提供者:命名管道提供程序,错误:40 - 无法打开与SQL Server的连接)
System.ComponentModel.Win32Exception:系统找不到指定的文件
---内部异常堆栈跟踪结束---
在System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject,UInt32 waitForMultipleObjectsTimeout,Boolean allowCreate,Boolean onlyOneCheckConnection,DbConnectionOptions userOptions,DbConnectionInternal& connection) 在System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject,TaskCompletionSource1 retry,DbConnectionOptions userOptions,DbConnectionInternal& connection) 在System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection,TaskCompletionSource1 retry,DbConnectionOptions userOptions,DbConnectionInternal oldConnection,DbConnectionInternal& connection) 在System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection,DbConnectionFactory connectionFactory,TaskCompletionSource1 retry,DbConnectionOptions userOptions) 在System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource1重试) 在System.Data.SqlClient.SqlConnection.Open() 在Hangfire.SqlServer.SqlServerStorage.CreateAndOpenConnection() 在Hangfire.SqlServer.SqlServerStorage.UseConnection [T](Func`2 func) 在Hangfire.SqlServer.SqlServerConnection.RemoveTimedOutServers(TimeSpan timeOut) 在Hangfire.Server.ServerWatchdog.Execute(BackgroundProcessContext context) 在Hangfire.Server.AutomaticRetryProcess.Execute(BackgroundProcessContext context)
所以我不知道在哪里处理此异常,以便在发生此异常时我可以停止我的应用程序。
答案 0 :(得分:1)
我认为你有两个选择:
try catch
IElectStateFilter
,特别是如果您希望对任何Hangfire作业具有相同的行为第一个选项很简单:
public void MyMethod() {
try {
//your code
}
catch(Exception ex) {
//stop application here
}
}
BackgroundJob.Enqueue(() => MyMethod());
第二个选项是这样的:
创建属性类:
public class MyFilterAttribute : JobFilterAttribute, IServerFilter, IElectStateFilter
{
public void OnStateElection(ElectStateContext context)
{
var failedState = context.CandidateState as FailedState;
if (failedState != null)
{
//job has failed, stop application here
}
}
}
注册过滤器:
GlobalConfiguration.Configuration.UseFilter(new MyFilterAttribute());
将属性添加到方法
[MyFilter]
public void MyMethod() {
//your code
}
照常调用您的代码:
BackgroundJob.Enqueue(() => MyMethod());
有关过滤器,请参阅documentation。
答案 1 :(得分:0)
如果注册自定义IJobFilterProvider,则必须在GetFilters方法的结果中包含GlobalFilters.Filters。例如:
public virtual IEnumerable GetFilters(Job job)
{
var result = GlobalJobFilters.Filters.AsEnumerable()
.Concat(new JobFilter[] {
new JobFilter(new QueueAttribute(GetQueueName(job)),
JobFilterScope.Method, null)
});
return result;
}
这对我有用!
答案 2 :(得分:0)
我通过检查存储是否已连接到hangfire来解决了这个问题。
try
{
IStorageConnection connection = JobStorage.Current.GetConnection();
return true;
}
catch (Exception e)
{
return false;
}