如何解决这个线程问题?

3

我正在使用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 导致了一个错误,该错误为“目标调用引发了异常”。

有人有任何想法如何可能解决这个问题吗?


8
请查看InnerException。 - SLaks
当您直接运行此代码时,即不在新线程中运行时,是否会抛出异常? - MattC
@JoEnos - 出现异常值不能为空 - HttpContext,但目前看不到它在哪里被引用。 - dotnetnoob
@JoeEnos,我认为我已经找到了使用IPAddress和UserAgent的方法。 - dotnetnoob
1
阅读InnerException堆栈跟踪。 - SLaks
显示剩余4条评论
1个回答

2
问题在于,您尝试激活的类可能正在尝试使用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服务或类似服务,并将这些任务代理给它,以便我对进程和线程有更好的控制。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接