如何解决这个线程问题?

时间:2021-11-21 00:33:52

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".

激活。CreateInstance会导致“调用目标抛出异常”的错误。

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

有没有人知道我该如何解决这个问题?

1 个解决方案

#1


2  

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.

问题是您试图激活的类可能正在尝试使用HttpContext。当前,后台线程上不存在,因为它保存在线程本地存储中。

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:

您需要更改它,以便它在请求线程上捕获HttpContext,并在激活类型之前将其设置在后台线程上:

    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.

同样值得注意的是IIS/ASP。NET线程/流程模型可能有点复杂,因此您可能希望在后台线程上执行此操作,也可能不希望这样做,具体取决于您的需求。例如,当没有更多未处理的请求时,IIS可以回收进程,但是您的后台线程可能仍然在运行。如果我需要运行需要运行完成的后台任务,我通常会将该功能拆分为单独的windows服务或类似的服务,并代理这些任务,以便更好地控制进程和线程。

#1


2  

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.

问题是您试图激活的类可能正在尝试使用HttpContext。当前,后台线程上不存在,因为它保存在线程本地存储中。

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:

您需要更改它,以便它在请求线程上捕获HttpContext,并在激活类型之前将其设置在后台线程上:

    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.

同样值得注意的是IIS/ASP。NET线程/流程模型可能有点复杂,因此您可能希望在后台线程上执行此操作,也可能不希望这样做,具体取决于您的需求。例如,当没有更多未处理的请求时,IIS可以回收进程,但是您的后台线程可能仍然在运行。如果我需要运行需要运行完成的后台任务,我通常会将该功能拆分为单独的windows服务或类似的服务,并代理这些任务,以便更好地控制进程和线程。