我希望在我的asp.net web api和asp.net MVC网站项目中实现hangfire.
我构建解决方案的方式如下:
解决方案 - 我的解决方案
1:模型 - (包含实体框架对象和类的项目)
2:服务(我实现所有>业务逻辑,更改等的地方)这是我最有可能使用HangFire的地方.3:Web API(我的asp.net api项目)
4:Web UI(mvc 5 Admin界面网站)
项目3和项目4都利用2:Services
项目来完成工作并调用执行业务逻辑的服务.这是大多数任务将被剥离的地方.
我将如何实现hangfire,以便他们各自的iis站点都可以使用hangfire的相同"实例".但它显然会在相关的应用程序池上运行?
或者它可能不能那样工作,我必须让它在一个地方运行?
我有什么选择,还有什么是推荐的方法?
我正在研究ASP.NET Core RC2应用程序.此应用程序需要定期调用某些任务,例如发送电子邮件或调用特定的业务逻辑.
我知道有一些第三方库,如Hangfire或Quartz.NET,可以提供开箱即用的调度功能.但是我不认为其中任何一个当前都支持ASP.NET Core RC2.是否有任何其他可用的选项与ASP.NET Core RC2兼容?
如果没有,我想一个可能的选择是在一个单独的Windows服务中使用这些第三方库之一,然后可以定位支持的.NET版本.然后,该服务可以通过其Web API定期向ASP.NET应用程序发出请求,以便调用任务.
但是我不希望有单独的服务,因为它增加了移动部件的数量并使我们的应用程序的部署变得复杂.
我已经开始阅读Hangfire文档,但没有发现任务限制.
如声明的那样,任务(或作业)存储在某处.
因为他们只是代表,所以唯一可以存储,据我所知,是一个代表"身体"(IL?).但是可能存在闭包,它为任务提供了一些上下文,例如,一些外部服务,可能需要加载额外的程序集来运行它们的代码等.
Hangfire如何处理这个问题?
任务可以包含其正文中的任何说明,还是有任何限制?
我在.NET Core Web应用程序的Startup类中安装并配置了Hangfire,如下所示(删除了很多非Hangfire代码):
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseHangfireServer();
//app.UseHangfireDashboard();
//RecurringJob.AddOrUpdate(() => DailyJob(), Cron.Daily);
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettings>(Configuration);
services.AddSingleton<IConfiguration>(Configuration);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IPrincipal>((sp) => sp.GetService<IHttpContextAccessor>().HttpContext.User);
services.AddScoped<IScheduledTaskService, ScheduledTaskService>();
services.AddHangfire(x => x.UseSqlServerStorage(connectionString));
this.ApplicationContainer = getWebAppContainer(services);
return new AutofacServiceProvider(this.ApplicationContainer);
}
}
public interface IScheduledTaskService
{
void OverduePlasmidOrdersTask();
}
public class ScheduledTaskService : IScheduledTaskService
{
public void DailyJob()
{
var container = getJobContainer();
using (var scope = container.BeginLifetimeScope())
{
IScheduledTaskManager scheduledTaskManager = scope.Resolve<IScheduledTaskManager>();
scheduledTaskManager.ProcessDailyJob();
}
}
private …
Run Code Online (Sandbox Code Playgroud) 我有一个ASP.NET MVC应用程序作为Hangfire客户端 - 它排队不同的工作.我正在使用SqlServerJobStorage
Hangfire.
目前我正在处理一个与Hangfire数据库没有连接的情况,并且未来连接的某个地方正在实例化.
目标是我的ASP.NET MVC应用程序应该在此之前继续工作.连接恢复后,它应该开始排队作业.
因此,应用程序将抛出异常Global.asax
:
Hangfire.GlobalConfiguration.Configuration.UseSqlServerStorage("EshopServiceHangfire");
Run Code Online (Sandbox Code Playgroud)
此外,所有工作队列也会抛出异常:
BackgroundJob.Enqueue<ISomeClass>(x => x.DoSomethingGreat(JobCancellationToken.Null));
Run Code Online (Sandbox Code Playgroud)
我把行Global.asax
放在try/catch块中,所以它不会抛出.当有人排队工作时,我想检查一下JobStorage.Current
,如果它没有初始化,我会尝试使用相同的代码再次启动它:
Hangfire.GlobalConfiguration.Configuration.UseSqlServerStorage("EshopServiceHangfire");
Run Code Online (Sandbox Code Playgroud)
有人知道这样做的方法吗?文档没有关于此的信息.
有点像Hangfire.GlobalConfiguration.JobStorage.IsInitialized
?
从Job enqueue捕获异常也是一种方式,但我不喜欢它,因为它抛出非特定的
InvalidOperationException:尚未初始化JobStorage.Current属性值.您必须在使用Hangfire客户端或服务器API之前进行设置.
非常感谢那些读过这个地方的人)
我正在尝试将 OnPrem 解决方案迁移到 Azure。该应用程序大量使用 Hangfire。Hangfire 托管在 Windows 服务中,并由 SQL Server 提供支持。
除非绝对需要,否则我不希望删除此依赖项。(替代方案是功能/网络作业。)
在 Azure 上运行 Hangfire 是否有任何指南/最佳实践?
如果不考虑存储特性的差异,Hangfire 是否会像在 OnPrem 上一样在 azure 上工作?
关于谷歌搜索 + 扫描 github 问题 & SO:
谢谢,帕托
我在 mvc 应用程序中使用 hangfire。我正在向用户发送预约提醒。我已经在我的应用程序中安装了 hangfire。我已经在 startup.cs 类中配置了 hangfire。但是当我运行该应用程序时,它会产生以下错误 JobStorage。当前属性值尚未初始化。您必须在使用 Hangfire Client 或 Server API 之前设置它。
using Hangfire;
using Hangfire.SqlServer;
using Microsoft.Owin;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using UKC.Data.Infrastructure;
using UKC.UI.Helper;
[assembly: OwinStartup(typeof(UKC.UI.App_Start.Startup))]
namespace UKC.UI.App_Start
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
GlobalConfiguration.Configuration
.UseSqlServerStorage("DbEntities");
app.UseHangfireDashboard();
app.UseHangfireServer();
}
}
}
Run Code Online (Sandbox Code Playgroud) 我们在带有SQL Server 2016的ASP.NET Web项目中使用Hangfire 1.7.2。我们的服务器上大约有150个站点,每个站点都使用Hangfire 1.7.2。我们注意到,当我们升级这些站点以使用Hangfire时,数据库服务器崩溃了。查看数据库日志,我们发现有多个锁定查询。我们在所有阻止会话中都标识了一个RPC事件“ sys.sp_getapplock; 1”。看来Hangfire锁定了我们的数据库,使整个数据库无法使用。由于Hangfire,我们注意到将近670多个锁定查询。
这可能是由于我们设置了以下属性:
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(30),
QueuePollInterval = TimeSpan.FromHours(5)
Run Code Online (Sandbox Code Playgroud)
每个站点大约有20个后台作业,其中一些每分钟运行一次,而另一些每小时,每6小时运行一次,每天运行一次。
我已经搜索了文档,但是找不到任何可以解释这两个属性或如何设置它们以避免数据库锁定的内容。
在这方面寻求帮助。
编辑:每秒执行以下查询:
exec sp_executesql N'select count(*) from [HangFire].[Set] with (readcommittedlock, forceseek) where [Key] = @key',N'@key nvarchar(4000)',@key=N'retries'
select distinct(Queue) from [HangFire].JobQueue with (nolock)
exec sp_executesql N'select count(*) from [HangFire].[Set] with (readcommittedlock, forceseek) where [Key] = @key',N'@key nvarchar(4000)',@key=N'retries'
Run Code Online (Sandbox Code Playgroud)
不管我们设置的时间跨度值的各种组合如何。这是我们正在使用的GetHangfirServers的代码:
public static IEnumerable<IDisposable> GetHangfireServers()
{
// Reference for GlobalConfiguration.Configuration: http://docs.hangfire.io/en/latest/getting-started/index.html
// Reference for UseSqlServerStorage: http://docs.hangfire.io/en/latest/configuration/using-sql-server.html#configuring-the-polling-interval
GlobalConfiguration.Configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(ConfigurationManager.ConnectionStrings["abc"]
.ConnectionString, new SqlServerStorageOptions
{
CommandBatchMaxTimeout = …
Run Code Online (Sandbox Code Playgroud) 如何在HangFire任务中添加日期?例如,此代码添加了7天:
BackgroundJob.Schedule(
() => Console.WriteLine("Reliable!"),
TimeSpan.FromDays(7));
Run Code Online (Sandbox Code Playgroud)
但是如果我需要在特定日期运行任务呢?
在 IIS 8+ 上托管(非核心)ASP.net 站点时,可以利用IIS 应用程序初始化模块在 IIS 启动时主动初始化(“预热”)Web 应用程序(或者,我相信,当应用程序池被回收时)。据我所知,在 IIS 上托管 .net Core 应用程序时这是不可能的。
我还注意到,在 IIS 上托管 .net Core (1.1) 应用程序时,dotnet.exe
进程 (Kestrel) 作为应用程序池回收事件的一部分被终止。此过程仅在发出第一个新请求时才重新启动。
我问以下问题是因为我正在使用 Hangfire (Core) 和一个经常性的后台作业,并且希望在没有人长时间访问该站点时仍然执行该作业。
在 IIS 上托管核心应用程序时,使用计划的应用程序池回收功能有什么意义吗?我能找到的唯一参考是 Github repo 上的一个问题。
如果是这样,是否可以在应用程序池回收后自动初始化站点或启动 Kestrel(通常默认情况下每 29 小时发生一次)。
iis hangfire kestrel-http-server asp.net-core asp.net-core-2.0
hangfire ×10
c# ×6
asp.net ×3
asp.net-core ×2
asp.net-mvc ×2
.net ×1
autofac ×1
azure ×1
date ×1
iis ×1
quartz.net ×1
sql-server ×1
task ×1