我需要在我的网络服务器上执行的异步任务中记录一些Elmah。但是当我尝试记录错误时,由于HttpContext而失败。
var httpContext = HttpContext.Current;
Task.Factory.StartNew(() =>
{
HttpContext.Current = httpContext;
try
{
//Execute some code
}
catch (Exception ex)
{
//Generate some error for the user and log the error in Elmah
try
{
ErrorLog.GetDefault(HttpContext.Current).Log(new Error(ex));
}
catch(Exception ex)
{
}
}
});
为了获得任务的进度,我实施了一些轮询机制。目前没有任何错误记录到Elmah,这使得难以解决它们。
同时提供上下文作为参数不起作用。
它不起作用。我得到一个ArgumentException告诉我预期值不在预期范围内。使用以下stacktrace:
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode,IntPtr errorInfo) 在System.Web.Hosting.IIS7WorkerRequest.GetServerVariableInternal(String name) 在System.Web.HttpRequest.AddServerVariableToCollection(String name) 在System.Web.HttpRequest.FillInServerVariablesCollection() 在System.Web.HttpServerVarsCollection.Populate() 在System.Web.HttpServerVarsCollection.Get(String name) 在Elmah.ErrorLog.InferApplicationName(HttpContext上下文) 在Elmah.ErrorLog.GetDefaultImpl(HttpContext context) 在Elmah.ServiceContainer.GetService(类型serviceType) 在Elmah.ServiceCenter.GetService(对象上下文,类型serviceType) 在Elmah.ErrorLog.GetDefault(HttpContext上下文) 在D:\ Users \ A500535 \ Documents \ Projecten \ Biobank \ Bis \ src \ Utilities \ Log \ ElmahErrorLog.cs:第13行中的Bis.Utilities.Log.ElmahErrorLog.TryLogError(异常执行)
答案 0 :(得分:5)
下面是一个可能完成工作的丑陋黑客。从本质上讲,它会在虚假Error
(原型)上创建Exception
对象,以便在请求仍在进行时捕获上下文。稍后,当任务因请求失败而启动时,将从发生的实际异常中创建另一个Error
对象,然后从早期原型中选择性地复制有趣和上下文位。不幸的是,无论是否发生异常,都必须创建原型Error
。
// Create an error that will capture the context
// and serve as a prototype in case a real exception
// needs logging
var prototype = new Error(new Exception(), context);
Task.Factory.StartNew(() =>
{
try
{
// Execute some code
}
catch (Exception ex)
{
// Generate some error for the user and log the error in ELMAH
try
{
// Create a new error without contextual information
// but then copy over the interesting bits from the
// prototype capture at time of request.
var error = new Error(ex)
{
HostName = prototype.HostName,
User = prototype.User,
};
error.ServerVariables.Add(prototype.ServerVariables);
error.QueryString.Add(prototype.QueryString);
error.Cookies.Add(prototype.Cookies);
error.Form.Add(prototype.Form);
ErrorLog.GetDefault(null).Log(error);
}
catch(Exception)
{
}
}
});
答案 1 :(得分:1)
当你启动一个新线程时,它不会获得HttpContext结构。由于Elmah日志记录需要HttpContext数据,因此它将失败。
请参阅以下QA: Elmah Does not email in a fire and forget scenario
对我而言,这适用于使用Task.Run调用的异步任务:
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new NotSupportedException("elmah logging test")));