Search code examples
c#multithreadingapihttpcontext

c# HttpContext.Current.Items is null in spawn thread


I have the following api method:

public IHttpActionResult Post(LogModel value)
{
        try
        {
            IDictionary items = HttpContext.Current.Items;
            Thread thread = new Thread(() => LogSQL.LogDetail(items, value));
            thread.Start();

            return Ok();
        }
        catch (Exception ex)
        {
            ...
        }
    }

Before hitting the controller, there is authentication and authorization code invoked, which saves some data in HttpContext.Current.Items.

For the new threat, HttpContext.Current.Items is null, so I'm passing the items data from the parent thread to set the one in the child's thread.

public static void LogDetail(IDictionary items, LogModel log)
    {
        var keys = (from System.Collections.DictionaryEntry dict in items
                           let key = dict.Key.ToString()
                           select key).ToList();

        foreach (var key in keys)
        {
            HttpContext.Current.Items[key] = items[key];
        }

... }

But this doesn't work. HttpContext.Current.Items is null and read-only, so I can't set it in any way.

I can pass the 'items' parm all over to whatever needs the data in the new thread, but trying to avoid it.

Any ideas on how to solve this? Any threading trick I could use?


Solution

  • HttpContext.Current is bound to the thread processing the HTTP request. If you spawn a new thread, it will not have that context associated with it.

    I can pass the 'items' parm all over to whatever needs the data in the new thread, but trying to avoid it.

    That is the correct approach. Extract anything you need from the current context and pass it to your thread.

    Note that it is somewhat dangerous to spawn threads while processing an HTTP request because

    • An unhandled exception in a thread not associated with a request will take down the process.
    • If you run your site in a Web Farm, you could end up with multiple instances of your app that all attempt to run the same task at the same time.
    • The AppDomain your site runs in can go down for a number of reasons and take down your background task with it.

    (Source, and a good read on the topic including better ways to do this)