我正在使用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导致错误,即“调用目标已抛出异常”。
任何人都知道如何才能解决这个问题?
答案 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服务或类似功能,并将这些任务代理到它,以便我可以更好地控制进程和线程。