如何解决这个线程问题

本文关键字:线程 问题 解决 何解决 | 更新日期: 2023-09-27 18:27:44

我正在使用Thread.Join来在新线程中启动一些功能。

不幸的是,我在部分代码中遇到了运行时错误,它是:

    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导致错误,错误为"调用的目标引发了异常"。

有人知道我该怎么解决这个问题吗?

如何解决这个线程问题

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

我想你正在做这样的事情:

    public void StartBackgroundRequest()
    {
        var thread = new Thread(StartMethod);
        thread.Start();
    }
    private void StartMethod()
    {
        //bunch of stuff
        var request = NewRequest(className); // exception gets throw here
    }

您需要更改它,以便它在激活类型之前捕获请求线程上的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
    }

我应该注意到,您正在激活的组件的实现可能会有额外的细微差别,这可能意味着它在多线程环境中不太好用,我不知道。

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