【问题标题】:c# HttpContext.Current.Items is null in spawn threadc# HttpContext.Current.Items 在 spawn 线程中为空
【发布时间】:2015-10-22 23:08:53
【问题描述】:

我有以下api方法:

public IHttpActionResult Post(LogModel value)
{
        try
        {
            IDictionary items = HttpContext.Current.Items;
            Thread thread = new Thread(() => LogSQL.LogDetail(items, value));
            thread.Start();

            return Ok();
        }
        catch (Exception ex)
        {
            ...
        }
    }

在点击控制器之前,会调用身份验证和授权代码,这会将一些数据保存在 HttpContext.Current.Items 中。

对于新威胁,HttpContext.Current.Items 为空,所以我从父线程传递项目数据以设置子线程中的数据。

public static void LogDetail(IDictionary items, LogModel log)
    {
        var keys = (from System.Collections.DictionaryEntry dict in items
                           let key = dict.Key.ToString()
                           select key).ToList();

        foreach (var key in keys)
        {
            HttpContext.Current.Items[key] = items[key];
        }

... }

但这不起作用。 HttpContext.Current.Items 是 null 并且是只读的,所以我不能以任何方式设置它。

我可以将“items”参数传递给新线程中任何需要数据的地方,但尽量避免它。

关于如何解决这个问题的任何想法?我可以使用任何线程技巧吗?

【问题讨论】:

  • 了解为什么您无法在衍生线程上获取上下文的最简单方法是查看当新衍生线程实际上直到请求结束才开始执行代码时会发生什么 - 您期望“当前" 设置在那个时候?

标签: c# multithreading api httpcontext


【解决方案1】:

HttpContext.Current 绑定到处理 HTTP 请求的线程。如果您生成一个新线程,它不会有与之关联的上下文。

我可以将“items”参数传递给新线程中任何需要数据的地方,但尽量避免它。

这是正确的方法。从当前上下文中提取您需要的任何内容并将其传递给您的线程。

请注意,在处理 HTTP 请求时产生线程有些危险,因为

  • 与请求无关的线程中未处理的异常将导致进程停止。
  • 如果您在 Web Farm 中运行您的网站,您最终可能会得到应用程序的多个实例,它们都尝试同时运行相同的任务。
  • 您的网站运行所在的 AppDomain 可能会因多种原因而关闭,并随之取消您的后台任务。

Source,以及有关该主题的好读物,包括更好的方法)

【讨论】:

  • 谢谢你,埃里克。我担心没有什么技巧可供我使用。该链接确实是一个很好的阅读。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多