Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I work round this threading issue?

I am using a Thread.Join to launch some functionality in a new thread.

Unfortunately I'm getting a runtime error in part of the code, here it is:

    IBuyerRequest NewRequest(string className)
    {
        className.ThrowNullOrEmpty("className");

        var type = Type.GetType(string.Format("MyApplication.BLL.PingtreeEngine.Requests.{0}Request", className));
        object[] args = { _appForm };

        type.ThrowNull("type");

        var instance = Activator.CreateInstance(type, args) as IBuyerRequest;

        return instance;
    }

Activator.CreateInstance is causing the error which is "Exception has been thrown by the target of an invocation".

Anyone got any idea as to how I could possible work round this?

like image 520
dotnetnoob Avatar asked Sep 11 '26 20:09

dotnetnoob


1 Answers

The problem is that the class you are trying to activate is probably attempting to use HttpContext.Current, which doesn't exist on the background thread as it is kept in thread-local storage.

I assume you are doing something like this:

    public void StartBackgroundRequest()
    {
        var thread = new Thread(StartMethod);
        thread.Start();
    }

    private void StartMethod()
    {
        //bunch of stuff
        var request = NewRequest(className); // exception gets throw here
    }

You need to change this so that it captures the HttpContext on the request thread and sets it on your background thread before activating the type:

    public void StartBackgroundRequest()
    {
        var thread = new Thread(StartMethod);
        thread.Start(HttpContext.Current);
    }

    private void StartMethod(object state)
    {
        HttpContext.Current = (HttpContext)state;

        //bunch of stuff
        var request = NewRequest(className); // exception gets throw here
    }

I should note that there may be additional nuances to the implementation of the component you are activating that may mean it doesn't play nice in a multi-threaded environment, I have no idea.

It's also noteworthy that the IIS/ASP.NET threading/process model can be a bit complex, so you may or may not want to actually do this on a background thread depending on your requirements. For example, IIS can recycle the process when there are no more outstanding requests, but your background thread might still be running. If I have a need to run background tasks that need to run to completion, I will usually split that functionality into a separate windows service or similar and proxy those tasks to it so that I have better control over the process and threads.

like image 70
Mike Marynowski Avatar answered Sep 15 '26 02:09

Mike Marynowski