【发布时间】:2018-09-17 01:44:26
【问题描述】:
我有一个在Application_Start 期间在Global.asax.cs 中设置的 Quartz 作业
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
Logger.log("About to Setup Retry Job");
JobScheduler.Start();
}
这会调用 Start 方法,然后安排作业。
作业每 20 秒运行一次并引发异常。这是我的工作。
public class RetryTempJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
try
{
Logger.log("Executing Job");
new ProcessOrder().retryFailedOrders();
//Logger.log("Done Executing Syspro Job");
await Console.Error.WriteLineAsync("Done Executing Syspro Job");
}
catch (Exception se)
{
await Console.Error.WriteLineAsync("" + se.InnerException);
}
}
}
Logger.log("Executing Job"); 这一行抛出异常。这是一个打开日志文件并写入的“静态方法”。此方法适用于我网站的其他任何地方。
这是异常消息: {"对象引用未设置为对象的实例。"}
InnerException 为 NULL。这是堆栈:
DarwinsShoppingCart.dll!DarwinsShoppingCart.SharedClasses.JobScheduler.RetrySyspro.Execute(Quartz.IJobExecutionContext context) Line 69 C#
Quartz.dll!Quartz.Core.JobRunShell.Run(System.Threading.CancellationToken cancellationToken) Unknown
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<Quartz.Core.JobRunShell.<Run>d__9>(ref Quartz.Core.JobRunShell.<Run>d__9 stateMachine) Unknown
Quartz.dll!Quartz.Core.JobRunShell.Run(System.Threading.CancellationToken cancellationToken) Unknown
Quartz.dll!Quartz.Core.QuartzSchedulerThread.Run.AnonymousMethod__0() Unknown
mscorlib.dll!System.Threading.Tasks.Task<System.Threading.Tasks.Task>.InnerInvoke() Unknown
mscorlib.dll!System.Threading.Tasks.Task.Execute() Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj) Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot) Unknown
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) Unknown
mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Unknown
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Unknown
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() Unknown
这是我的 Logger 类代码
public static void log(string strLog)
{
StreamWriter log;
FileStream fileStream = null;
DirectoryInfo logDirInfo = null;
FileInfo logFileInfo;
string username = Environment.UserName;
string logFilePath = HttpContext.Current.Server.MapPath("~/log/Log.txt");
logFileInfo = new FileInfo(logFilePath);
logDirInfo = new DirectoryInfo(logFileInfo.DirectoryName);
double fileSize = ConvertBytesToMegabytes(logFileInfo.Length);
if (fileSize > 30)
{
string FileDate = DateTime.Now.ToString().Replace("/", "-").Replace(":", "-");
string oldfilepath = HttpContext.Current.Server.MapPath("~/log/log-" + FileDate + ".txt");
File.Move(logFileInfo.FullName, oldfilepath);
}
if (!logFileInfo.Exists)
{
fileStream = logFileInfo.Create();
}
else
{
fileStream = new FileStream(logFilePath, FileMode.Append);
}
log = new StreamWriter(fileStream);
log.WriteLine(DateTime.Now.ToString("MM-dd HH:mm:ss") + " " + username + " " + strLog);
log.Close();
}
【问题讨论】:
-
发布您的
Logger课程代码。如果您在石英下运行时尝试访问HttpContext,那么您的日子不好过——我曾经有过same issue。 -
@BagusTesa 我添加了记录器类代码
-
好吧,我仍然支持我的猜测,您在请求中调用
HttpContext.Current是一个问题。Quartz在执行其任务时,它不绑定到任何请求和HttpContext.Current可以返回空值。您必须找到另一种方法来找到真正的路径,而不依赖HttpContext,可能使用HttpRuntime.AppDomainPathor some other。虽然我不确定他们在Quartz的线程中的表现如何.. 我还没有尝试过自己.. -
有没有办法创建一个网络服务并从石英作业发布到该网络服务?
-
实际上,有一个 hack,您可以将大部分代码逻辑放入某种端点,然后让
Quartz作业使用 WebClient 或从Quartz作业中访问该端点HttpClient 或其他任何东西。 hacky,但可以完成工作。
标签: c# asp.net quartz-scheduler quartz.net