【问题标题】:How to pass object from one thread to another without using state object如何在不使用状态对象的情况下将对象从一个线程传递到另一个线程
【发布时间】:2011-04-29 23:02:57
【问题描述】:

我有一个 ASP.NET 应用程序,它使用类库程序集中的一个组件来进行 Web 服务调用。该组件使用线程池或某种自制线程解决方案来生成后台线程,在这些线程中进行同步 Web 服务调用。

日志组件在 ASP.NET 应用程序中使用,并且由组件从后台线程调用的助手类使用,该线程在执行服务调用时产生。

在 ASP.NET 中,HttpModule 创建日志上下文对象并将其存储在 HttpContext.Current.Items 集合中。当需要记录消息时,在 ASP.NET 应用程序和帮助器类中使用的帮助器类从 HttpContext.Current.Items 获取记录上下文对象,以便使用将记录的消息放入上下文的信息来装饰记录的消息.

当直接从 ASP.NET 调用助手类时,HttpContext.Current 可用。

当从组件创建的后台线程调用助手类时,HttpContext.Current 为空,因此在记录消息时它们没有可用的记录上下文;记录的消息是无用的。

我无法控制创建用于进行服务调用的线程的组件。如果我这样做了,我会安排将日志记录上下文对象复制并传递到子线程中。

我的日志记录上下文对象不能是静态的,因为它会被并发的 ASP.NET 请求线程覆盖,这会很糟糕。

我的日志记录上下文对象(简单的 int/string 属性)的成员可以标记为 ThreadStatic,这样可以正常工作,并且我不再需要使用 HttpContext.Current.Items。

我真正需要的是让 .NET 运行时复制对象(或者甚至传递一个引用;两者都可以)并使其自动可供子线程使用。

我想知道是否可以将 元素添加到 web.config 并指定一个帮助程序类来创建线程,就像在 %lt;system.net 中为 Web 请求所做的那样>

我还想知道是否可以用一些属性标记我的 Logging Context 对象,使其自动复制。

我查看了 log4nets LogicalThreadContext,试过了,但是没有用。我认为这是为了跨进程或应用程序域边界传递日志记录上下文信息。

log4net的LogicalThreadContext在后台使用了什么机制?来自 System.Runtime.Remoting 的东西?现在已经弃用了吗?

我的环境是 .NET 4,所以也许通过 .NET 4 中线程的并行扩展或增强,这现在是可能的。

有人知道这是否可能吗?我开始不这么认为了。

  • 更新 *

我必须执行以下操作:

Task<IEnumerable<Account>> accountsTask = Task<IEnumerable<Account>>.Factory.StartNew
    (
        instrumentationContext =>
            {
                var parentContext = instrumentationContext as Site.Instrumentation.InstrumentationContext;
                if (Site.Instrumentation.InstrumentationContext.Current == null && parentContext != null)
                    Site.Instrumentation.InstrumentationContext.Current = parentContext;
                return GetAccounts();
            },
        Site.Instrumentation.InstrumentationContext.Current
    );

GetAccounts() 方法调用另一个类,而后者又依赖于 Site.Instrumentation.InstrumentationContext.Current

问题是,我宁愿不必更改代码以显式传入并在子线程中设置此状态对象 - 我希望 .NET Framework 自动为我执行此操作,以便代码(上图)创建任务的方法并不明智,也不必更改。

如果没有其他人提供替代方案,Jon 会得到绿色勾号,因为我认为这是我唯一现实的选择,尽管任务不是线程。

【问题讨论】:

  • 发布一些代码以了解您正在做什么并试图实现的目标。把你所有的问题都集中在一个人的脑海里并提出建议真的很难。

标签: c# asp.net multithreading .net-4.0 log4net


【解决方案1】:

如果我理解正确,您需要做的就是将对象传递给线程签名,那么参数化线程启动有什么问题??

static void Main(string[] args)
    {
        object j = new object();
       Thread t = new Thread(()=>childThread(j));
       t.Start();
    }

    private static void childThread(object someObject)
    {
        // do work
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 2015-06-14
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    相关资源
    最近更新 更多