所以我的问题如下:我正在调度/使用Hangfire的方法/功能使用NLog执行大量相关信息的记录.在没有hangfire的情况下运行方法时,我得到了我想要的所有日志记录信息,但是当我使用hangfire安排方法时,所有这些日志记录都将丢失.
我知道Hangfire使用NLog(或您喜欢的任何其他日志框架)来进行自己的日志记录.我正在使用ASP.NET MVC4 Web应用程序中的Hangfire.我正在使用Ninject并使用OWIN Startup类设置hangfire,目前看起来像这样:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseHangfire(config =>
{
var kernel = new StandardKernel(new MyModule());
config.UseNinjectActivator(kernel);
config.UseSqlServerStorage("Context");
LogProvider.SetCurrentLogProvider(new NLogLogProvider());
config.UseServer();
});
}
}
Run Code Online (Sandbox Code Playgroud)
我想要完成的是Hangfire可以自己进行日志记录,而我的预定作业也可以完成所有日志记录,我并不关心它在一个或多个文件中.目前,Hangfire正在正确进行日志记录,即:
2015-02-25 14:32:41.4400|TRACE|Hangfire.Server.AutomaticRetryServerComponentWrapper|Sending start request for server component 'Server Bootstrapper'...
Run Code Online (Sandbox Code Playgroud)
等等
但是,从预定的工作中进行的记录无处可见.
我想问的是:我如何从预定的方法/工作中进行记录?我的猜测是我错过了某个地方的依赖/背景,但我真的没有任何线索.
此文档说明您可以通过使用Queue要调用的方法的属性来指定队列.这假设您始终希望在同一队列上执行方法.是否有一种方法可以调用进程Enqueue来指定要将作业放入队列的名称(有效地将决策权交给作业生成器,而不是作业的定义).
如何在HangFire任务中添加日期?例如,此代码添加了7天:
BackgroundJob.Schedule(
() => Console.WriteLine("Reliable!"),
TimeSpan.FromDays(7));
Run Code Online (Sandbox Code Playgroud)
但是如果我需要在特定日期运行任务呢?
我正在使用asp.net mvc-5 Web应用程序,我在使用Hangfire工具运行长时间运行的后台作业时遇到了问题.问题是如果作业执行超过30分钟,那么hangfire会自动启动另一个作业,所以我最终会同时运行两个类似的作业.
现在我有以下内容: -
现在我已经定义了一个每天17:00运行的篝火重复工作.后台作业主要扫描我们的网络中的服务器和虚拟机并更新数据库,定期作业将在完成执行后发送电子邮件.经常性工作在执行时间不到30分钟时效果很好.但是今天随着我们的系统的发展,经常性的工作在40分钟后完成,而不是像过去那样在22-25分钟之后完成.我收到了2封电子邮件,而不是一封电子邮件(电子邮件之间的时间约为30分钟).现在我手动重新运行这个工作,我注意到问题如下: -
"当定期作业达到30分钟连续执行时,定期作业的新实例将启动,因此我将有两个实例而不是同时运行的实例,这就是我收到2封电子邮件的原因."
现在,如果定期工作不到30分钟(例如29分钟),我将不会遇到任何问题,但如果重复执行的工作超过30分钟,那么由于某种原因或其他原因,将启动新工作.虽然当我在执行作业期间访问hangfire仪表板时,我发现只有一个活动作业,当我监视我的数据库时,我可以从sql profiler看到有两个作业访问数据库.这种情况发生在经常性工作开始30分钟后(在我们的案例中是17:30),这就是为什么我收到2封电子邮件,这意味着2个重复工作在后台运行而不是一个.
那么有人可以提出这方面的建议吗,如果目前的重复工作执行时间超过30分钟,我怎么能避免因自动启动新的定期工作而导致绞火?谢谢
在 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,结果发现我们确实达到了数据库连接最大限制。
我们有大约 45 个连接用于hangfire,这对于维护一些长时间运行的任务来说似乎有点太多了。
我想知道是否可以采取任何措施来更改连接数,但是,我在配置中找不到提供此类配置的任何内容。
我试图创建多个队列,每个队列应该只有一个工作人员计数。所以我做了下面的代码:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHangfireDashboard("/scheduler", new DashboardOptions
{
Authorization = new[] { new HangFireAuthorization() },
AppPath = "/"
});
app.UseHangfireServer(new BackgroundJobServerOptions()
{
ServerName = string.Format("{0}:facebookqueue", Environment.MachineName),
Queues = new[] { "facebookqueue" },
WorkerCount = 1
});
app.UseHangfireServer(new BackgroundJobServerOptions()
{
ServerName = string.Format("{0}:googlequeue", Environment.MachineName),
Queues = new[] { "googlequeue" },
WorkerCount = 1
});
RecurringJob.AddOrUpdate<IScheduledJobs>(recurringJobId:
"FacebookExtractorJobYesterday",
methodCall: services => services.RecurringJobYesterday(null,
JobCancellationToken.Null),
cronExpression: cronExp, timeZone: TimeZoneInfo.Local, queue: "facebookqueue");
RecurringJob.AddOrUpdate<IGoogleScheduledJobs>(recurringJobId:
"GoogleExtractorJobYesterday",
methodCall: services => services.RecurringJobYesterday(null,
JobCancellationToken.Null),
cronExpression: cronExp, timeZone: …Run Code Online (Sandbox Code Playgroud) hangfire 文档指出:
原始 SQL Server 作业存储实现的主要缺点之一——它使用轮询技术来获取新作业。从 Hangfire 1.7.0 开始,当设置了 SlidingInvisibilityTimeout 选项时,可以使用 TimeSpan.Zero 作为轮询间隔。
我按照建议使用这些 SqlServerStorageOptions:
var options = new SqlServerStorageOptions
{
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero
};
Run Code Online (Sandbox Code Playgroud)
它没有说明 SlidingInvisibilityTimeout 的实际含义,谁能澄清一下?
我的情况是,我每天早上有大约 1000 封电子邮件要发送,而且我一直在突破每分钟 30 封邮件的 Office365 限制并被拒绝,所以我使用 Hangfire 将它们排在一个工作线程中,并添加了一个每个任务结束时 2 秒 Thread.Sleep。这很好用,但我的 CPU 使用率增加了大约 20% 由 hangfire 引起(如此处报告的那样),并且在服务器繁忙时导致频繁超时。
我试图实现的行为是:
感谢您的帮助。
想象一下,在 ASP.NET Core 中我注册了一个依赖项,如下Scoped所示:
IServiceCollection services = ...
services.AddScoped<IEmailService, EmailService>();
Run Code Online (Sandbox Code Playgroud)
然后我知道对于每个 HTTP 请求,scope都会创建一个新的请求,并且Email会重用一个新的服务实例。此外,同样的情况scope将在请求的生命周期内持续存在。
现在,假设我添加了一个 Hangfire 后台作业,如下所示:
RecurringJob.AddOrUpdate<IServiceA>("DoA", s => s.DoA(), Cron.Daily());
Run Code Online (Sandbox Code Playgroud)
在哪里
public class ServiceA: IServiceA {
public ServiceA(IEmailService emailService) { ... }
public void DoA() { ... }
}
Run Code Online (Sandbox Code Playgroud)
我想了解scopedhangfire工作术语中的含义,默认情况下,hangfire
有关如何配置它的解释的奖励积分。
我正在尝试将 Hangfire JobId (和其他属性)添加到我的所有作业中,而不必将其添加到每个作业方法中。
在 Startup.cs 中,我添加了一个有前途的过滤器解决方案,但是我不知道如何将其应用到我的测试方法中,我什至不确定这是否是正确的方法。
启动.cs
...
GlobalJobFilters.Filters.Add(new JobLoggerAttribute());
Run Code Online (Sandbox Code Playgroud)
JobLoggerAttribute类 - 来自此处: 链接
我的任务是将 JobId 放置在列单元格当前为空白的位置,而无需手动将其添加到我的测试方法中:

Program.cs(全局定义的Logger):
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.WriteTo.Elasticsearch....
.Enrich.FromLogContext()
.CreateLogger();
Run Code Online (Sandbox Code Playgroud)
因为我还想检索方法名称等。我添加了这个类来调用我的工作中的 Here 方法。
LoggerExtensions.cs:
public static class LoggerExtensions
{
public static ILogger Here(this ILogger logger,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0
)
{
return logger
.ForContext("MemberName", memberName)
.ForContext("FilePath", sourceFilePath)
.ForContext("LineNumber", sourceLineNumber)
;
}
}
Run Code Online (Sandbox Code Playgroud)
运行测试任务:
public void RunTestTask(PerformContext context)
{
// instead of …Run Code Online (Sandbox Code Playgroud)