Log in to Elmah in async Task

I need some Elmah logging in the async task running on my web server. But when I try to register an error, it fails due to the 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) { } } }); 

To make progress in the task, I implemented some kind of polling mechanism. Currently, none of the errors are logged in Elmah, which makes them difficult to resolve.

Also, providing context as a parameter does not work.

This does not work. I get an ArgumentException saying that the expected value does not fall into the expected range. Using the following stacktrace command:

in System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal (Int32 errorCode, IntPtr errorInfo) in System.Web.Hosting.IIS7WorkerRequest.GetServerVariableInternal (row name) in System.Web.HttpRequest.AddTerVer.arver.verververvalve.ververveverwerverveverwerverwerverwerverwerverwerwerwerwerver FillInServerVariablesCollection () in System.Web.HttpServerVarsCollection.Populate () in System.Web.HttpServerVarsCollection.Get (string name) in Elmah.ErrorLog.InferApplicationName (HttpContext context) in Elmah.ertextLeftrlfrtltext.rtleftextertext.rtleftextertext.rtlfer.errtltext.rtlf.textrleftpreference GetService (type serviceType) in Elmah.ServiceCenter.GetService (object context, type serviceType) in Elmah.ErrorLog.GetDefault (HttpContext context) in Bis.Utilities.Log.ElmahErrorLog.TryLogError (Exception \ exeption) D500: Documents \ Projecten \ Biobank \ Bis \ src \ Utilities \ Log \ ElmahErrorLog.cs: line 13

+4
source share
2 answers

Below is one ugly hack that can do its job. Essentially, it creates an Error object on a dummy Exception (prototype) so that the context can be captured while the request is still in flight. Later, when a task was launched as a result of a request failure, another Error object is created with the actual exception that occurred, and then interesting and contextual bits are selectively copied from an earlier prototype. Unfortunately, the Error prototype must be created regardless of whether an exception occurs.

 // 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) { } } }); 
+5
source

When you start a new thread, it does not get the HttpContext structure. Since Elmah logging requires HttpContext data, it will fail.

See the following QA: Elmah Does not send email in fire and forget mode

for me it worked in an async task named Task.Run:

 Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new NotSupportedException("elmah logging test"))); 
+1
source

All Articles