2

我有这个类会触发一个方法并忘记它。唯一的问题是,如果正在调用的方法有一个HttpContext它会抛出NullReferenceException

我的猜测是我不能Httpcontext在里面使用,ThreadPool.QueueUserWorkItem(dynamicInvokeShim, new TargetInfo(d, args));因为我得到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());
          }
      }
  }
}
4

2 回答 2

6

就像 usr 说的:HttpContext.Current仅在执行请求的线程上可用,并且您启动的线程池线程不是同一个线程。

但是,如果您想访问 ASP.NET 缓存,您也可以使用HttpRuntime.Cache,这是每个线程都可用的静态属性。(HttpContext.Current.Cache只需返回HttpRuntime.Cache,因此您无需担心任何差异。)

请注意,不建议将接收到的 HttpContext 实例传递HttpContext.Current给另一个线程:当另一个线程运行时,与捕获的 HttpContext 对应的请求可能已经结束,因此您最终可能会得到一个损坏的 HttpContext 实例。

于 2012-05-25T21:30:08.133 回答
1

是的,HttpContext.Current仅在执行 HTTP 请求的线程上可用。一个简单的解决方法是将表达式的结果传递(DataTable)HttpContext.Current.Cache[name]给线程,这样线程本身就不需要访问HttpContext. 或者,将HttpContext.Current对象传递给线程。

如何将数据传递给线程或任务超出了这个问题的范围,但你会在网上找到很多关于它的信息。

于 2012-05-25T20:04:49.177 回答