我如何解决这个线程问题?

时间:2013-08-15 15:10:31

标签: c# asp.net multithreading

我正在使用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导致错误,即“调用目标已抛出异常”。

任何人都知道如何才能解决这个问题?

1 个答案:

答案 0 :(得分: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服务或类似功能,并将这些任务代理到它,以便我可以更好地控制进程和线程。