在异步任务中登录Elmah

Mar*_*rco 4 model-view-controller logging elmah asp.net-mvc-3

我需要在我的网络服务器上执行的异步任务中记录一些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)
                {
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)

为了获得任务的进展,我实施了一些轮询机制.目前没有任何错误记录到Elmah,这使得难以解决它们.

同时提供上下文作为参数也不起作用.

它不起作用.我得到一个ArgumentException告诉我预期值不在预期范围内.使用以下堆栈跟踪:

在System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(的Int32的errorCode,IntPtr的errorInfo中)在System.Web.Hosting.IIS7WorkerRequest.GetServerVariableInternal(字符串名称)在System.Web.HttpRequest.AddServerVariableToCollection(字符串名称)在System.Web.HttpRequest.位于Elmah.ServiceContainer的Elmah.ErrorLog.GetDefaultImpl(HttpContext上下文)的Elmah.ErrorLog.InferApplicationName(HttpContext上下文)的System.Web.HttpServerVarsCollection.Get(String name)处的System.Web.HttpServerVarsCollection.Populate()处的FillInServerVariablesCollection(). GetService的(类型的serviceType)在Elmah.ServiceCenter.GetService(对象上下文中,类型的serviceType)在Elmah.ErrorLog.GetDefault(HttpContext的上下文)在Bis.Utilities.Log.ElmahErrorLog.TryLogError(例外exeption)在d:\ Users\A500535\Documents\Projecten\Biobank\Bis\src\Utilities\Log\ElmahErrorLog.cs:第13行

Ati*_*ziz 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)
        {
        }
    }
});
Run Code Online (Sandbox Code Playgroud)