如何在不使用状态对象的情况下从一个线程传递对象到另一个线程

本文关键字:对象 线程 另一个 一个 情况下 状态 | 更新日期: 2023-09-27 17:54:05

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

日志组件在ASP. js中使用。. NET应用程序,以及组件在执行服务调用时从生成的后台线程中调用的helper类。

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

当从ASP中直接调用helper类时。净,HttpContext。电流可用

当从组件创建的后台线程调用helper类时,HttpContext。Current为null,因此在记录消息时没有日志上下文可供它们使用;记录的消息是无用的。

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

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

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

我真正需要的是使。net运行时复制对象(甚至传递引用;两者都可以),并使子线程可以自动使用。

我想知道我是否可以添加一个元素到web。配置并指定一个帮助类来创建线程,就像您可以在%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框架自动为我做这件事,这样创建任务的代码(上面)是不明智的,不需要改变。

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

如何在不使用状态对象的情况下从一个线程传递对象到另一个线程

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

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
    }