.net 这个问题的可行解决方案?

.net 这个问题的可行解决方案?,.net,threadstatic,.net,Threadstatic,我从一段代码通过几层第三方代码进行调用,调用在某个时候通过调用我编写的一些代码返回到我的代码中 换句话说,代码调用链如下所示: My code #1 --> 3rd party code --> My code #2 internal static class DataHolder { [ThreadStatic] internal static ClassName FieldName; } 有其他解决方案吗?ThreadLocal针对.NET 4,如本问题所述: 然而,由于

我从一段代码通过几层第三方代码进行调用,调用在某个时候通过调用我编写的一些代码返回到我的代码中

换句话说,代码调用链如下所示:

My code #1 --> 3rd party code --> My code #2
internal static class DataHolder
{
    [ThreadStatic]
    internal static ClassName FieldName;
}
有其他解决方案吗?

ThreadLocal
针对.NET 4,如本问题所述:


然而,由于我自己也在那艘船上,我最终选择了静态路线。它工作正常而且安全,因为它处于可管理状态。

是的
ThreadStatic
将适用于此。您可能需要研究,这简化了线程静态变量的使用。

是的,[ThreadStatic]应该在您描述的场景中工作,前提是您可以绝对确定第三方代码总是在您调用第三方代码的同一线程上回叫您。在许多异步回调模型中,这通常无法保证。如果回调被严格定义为同步回调,那么您可能就可以了。

与其他答案表明这是可以的相比,您应该非常小心在ASP.NET应用程序中使用
ThreadStatic
ThreadLocal

ASP.NET利用线程敏捷性,这意味着同一请求可能由多个线程处理。为了安全起见,您需要破坏封装并将项目存储在当前的
HttpContext
,而不是使用
ThreadStatic
ThreadLocal

不幸的是,这个线程敏捷性“特性”的文档很少。我可以合理地确定线程切换只能在生命周期中的某些点上发生,而不是任意发生,因此根据代码在生命周期中的具体使用方式和位置,您可以使用
ThreadStatic
ThreadLocal
安全


我将尝试挖掘一些链接…

您必须将第三方代码交给某种类型的代理才能获得回电。这应该给你一种方法来挂起一个对象。不幸的是,它不是那么简单,唯一可以挂起一个事件的地方是通过一个静态事件(不要挂起我,我没有设计那个sh**),所以第三方库中只有一个公共表面点。事件是静态的并不重要,您创建的委托实例很重要。与SystemEvents相比,确实如此,我已经通过reflector进行了验证,所以这不是问题。仅仅因为第三方代码现在在同一线程上调用您并不意味着它总是会调用。该实现可能会在第三方代码的未来版本中发生更改,或者您的测试用例可能不会对其造成足够的影响,从而导致它“溢出”到其他工作线程中。如果第三方文档声明回调将在同一个线程上调用,那么可信度更高。经验观察对于做出这种规模的体系结构决策来说是很危险的。举个例子:LukeH关于ASP.NET“线程敏捷性”的注释正是那种会对使用线程本地存储造成影响的东西。在这个项目中,第三方库只有一条升级路径,这将被重写或替换。静态事件并不是它唯一的问题,但不幸的是,它做得足够好,我能够按时交付项目,尽管其中有一些不需要的部分,但现在它开始变得比重写/替换更痛苦,所以这只是一个短期补丁。你知道这些点在哪里吗?在本例中,调用链基本上是我调用第三方代码,该代码通过静态事件调用我的代码,这意味着最终得到目标调用的是同一个实例(如果有)。由于第三方代码与ASP.NET没有关联,因此没有涉及ASP.NET代码。尽管这可能意味着我必须将这部分代码分层,以便在非ASP.NET中使用ThreadStatic或ThreadLocal,而在ASP.NET中我需要使用HttpContext.Current,没有涉及到的代码实际上关心任何一种方式。@Lasse:有很多轶事证据——只要将“线程敏捷性asp.net”插入谷歌——但我过去一直在努力,没有成功地找到任何确定的文档。这是一个很好的治疗方法。好吧,听起来我需要进一步调查。。。或者,也许重写/替换此文件的时间终于到来了。
internal static class DataHolder
{
    internal static ClassName PropertyName
    {
        get { return (ClassName)System.Web.HttpContext.Current.Items["foo"]; }
        set { System.Web.HttpContext.Current.Items["foo"] = value; }
    }
}