ThreadPool QueueUserWorkItem 在 HttpContext 目标上出现错误
本文关键字:错误 目标 QueueUserWorkItem HttpContext ThreadPool | 更新日期: 2023-09-27 18:35:31
我有这个类,它触发了一个方法并忘记了它。 唯一的问题是,如果 AM 调用的方法有HttpContext
它会抛出NullReferenceException
。
我的观点是我不能在ThreadPool.QueueUserWorkItem(dynamicInvokeShim, new TargetInfo(d, args));
内使用Httpcontext
,因为我正在NullReferenceException
有解决方法吗?
带Httpcontext
的方法:
public static DataTable GetDataTable(string name)
{
return (DataTable)HttpContext.Current.Cache[name];
}
触发并忘记方法的方法:
using System;
using System.Threading;
namespace XGen.Kuapo.BLL
{
public class AsyncHelper
{
class TargetInfo
{
internal TargetInfo(Delegate d, object[] args)
{
Target = d;
Args = args;
}
internal readonly Delegate Target;
internal readonly object[] Args;
}
private static WaitCallback dynamicInvokeShim = new WaitCallback(DynamicInvokeShim);
public static void FireAndForget(Delegate d, params object[] args)
{
ThreadPool.QueueUserWorkItem(dynamicInvokeShim, new TargetInfo(d, args));
}
static void DynamicInvokeShim(object o)
{
try
{
TargetInfo ti = (TargetInfo)o;
ti.Target.DynamicInvoke(ti.Args);
}
catch (Exception ex)
{
// Only use Trace as is Thread safe
System.Diagnostics.Trace.WriteLine(ex.ToString());
}
}
}
}
就像 usr 说的:HttpContext.Current
仅在执行请求的线程上可用,而您启动的线程池线程不是同一个线程。
但是,如果要访问 ASP.NET 缓存,也可以使用 HttpRuntime.Cache
,这是一个可从每个线程获得的静态属性。(HttpContext.Current.Cache
只是返回HttpRuntime.Cache
,因此您无需担心任何差异。
请注意,不建议将从HttpContext.Current
收到的 HttpContext 实例传递给另一个线程:当另一个线程运行时,与捕获的 HttpContext 对应的请求可能已经结束,因此您最终可能会得到一个损坏的 HttpContext 实例。
是的,HttpContext.Current
仅在执行 HTTP 请求的线程上可用。一个简单的解决方法是将表达式(DataTable)HttpContext.Current.Cache[name]
的结果传递给线程,这样线程本身就不需要访问HttpContext
。或者,将HttpContext.Current
对象传递给线程。
如何将数据传递给线程或任务超出了这个问题的范围,但您会在网络上找到很多关于它的信息。