标签: threadstatic

继承ThreadStatic值以在多线程上下文中的C#/ .NET中实现动态范围

有没有办法让新生成的线程在其父线程上继承ThreadStatic状态(或类似的东西)的值?我想使用这个(或类似的东西)来实现"动态范围"的特殊变量,其中包含用于跟踪/记录等的操作/任务上下文信息.这是一种合理的方法,是否可以使其工作?

c# logging scope threadstatic

6
推荐指数
1
解决办法
756
查看次数

C#ThreadStatic + volatile成员未按预期工作

我正在阅读帖子中的提示和技巧,我想我会尝试一些我之前从未做过的C#.因此,以下代码没有实际用途,但只是一个'测试函数'来查看发生了什么.

无论如何,我有两个静态私有字段:

private static volatile string staticVolatileTestString = "";
[ThreadStatic]
private static int threadInt = 0;
Run Code Online (Sandbox Code Playgroud)

如您所见,我正在测试ThreadStaticAttributevolatile关键字.

无论如何,我有一个看起来像这样的测试方法:

private static string TestThreadStatic() {
    // Firstly I'm creating 10 threads (DEFAULT_TEST_SIZE is 10) and starting them all with an anonymous method
    List<Thread> startedThreads = new List<Thread>();
    for (int i = 0; i < DEFAULT_TEST_SIZE; ++i) {
        Thread t = new Thread(delegate(object o) {
            // The anon method sets a newValue for threadInt and prints the …
Run Code Online (Sandbox Code Playgroud)

c# multithreading volatile threadstatic

6
推荐指数
1
解决办法
1872
查看次数

从.NET Profiler访问ThreadStatic字段

stackoverflow中的这个问题询问[ThreadStatic]是如何实现的: ThreadStatic属性如何工作?

有人建议将它视为Thread对象的扩展.我不确定这是否意味着它基于win32 TLS.

我的问题是,我可以以某种方式从.NET Profiler代码中的当前线程访问[ThreadStatic]的值吗?也就是说,在本机代码中.

例如,如果我能找到使用win32线程id的内存中所有线程静态字段的区域,并找到我需要检索的特定字段.

谢谢

.net c# profile threadstatic

6
推荐指数
1
解决办法
111
查看次数

WCF 请求处理线程敏捷吗?

我看过很多关于敏捷 Asp.Net 请求处理的文档?我想知道 WCF 请求处理的情况是否相同。我们可以依靠启动 Wcf 请求处理的 Thread 完成它的事实吗?

我正在维护一个 Wcf 应用程序,其中在很多地方都使用了 ThreadStatic 变量。虽然代码正在运行,但它可靠吗?值得改变它还是应该保持原样?

asp.net wcf multithreading threadstatic

5
推荐指数
1
解决办法
1592
查看次数

可以自动处理ThreadStatic IDisposable吗?

这不是一个如何自动调用dispose的问题 - 我的问题恰恰相反:我有一个线程池,其中每个线程都有一个ThreadStatic Graphics(由Image创建)来执行文本大小测量.现在我遇到了一个问题,即不时读取TextRenderingHint属性失败(导致ArgumentException),图形似乎被处理掉了.

是否存在一些处理图形的机制,例如,如果线程长时间处于空闲状态?

.net c# graphics idisposable threadstatic

5
推荐指数
1
解决办法
1161
查看次数

为什么ThreadStatic数据在线程之间意外共享?

我有一个我编写的日志框架,它能够跟踪"日志记录上下文".它有一个可插拔的策略框架,但我最常使用的是ThreadStatic变种,它跟踪[ThreadStatic]变量中的上下文.我一直在尝试解决多线程工作流中的日志记录上下文问题.目标是让所有共享公共线程的方法和类的所有调用的所有日志条目记录相同的上下文信息.因为理论上每个线程都应该获得自己的ThreadStatic变量,所以这个想法似乎很容易.

public class ThreadStaticLoggingContextStrategy: ILoggingContextStrategy
{
    public ThreadStaticLoggingContextStrategy()
    {
        Debug.WriteLine("[INITIALIZE] A new instance of 'ThreadStaticLoggingContextStrategy' has been created.");
    }

    [ThreadStatic] private LoggingContext _context;

    public LoggingContext GetLoggingContext()
    {
        if (_context == null)
            _context = new LoggingContext();

        return _context;
    }
}
Run Code Online (Sandbox Code Playgroud)

实际上,似乎ThreadStatic数据实际上是跨线程共享的.这违背了我对线程的理解.我很难搞清楚问题是什么,直到我投入额外的日志条目,跟踪每个线程清除线程上下文时(所有线程在主循环上运行...在开始时,如果必要的消息是收到,上下文被初始化,并且在finally子句的最后,它被重置.)以下日志记录是CONSISTENT:

[2011-12-15 16:27:21,233] [DEBUG] [TPI.LTI.Eventing.GroupCreatedNotificationHandler:TPI.LTI.Provisioning.Handlers.GroupCreatedNotificationHandler.WORKDEVELOPMENT.1_Thread:324] :( ContextId = 184e82dd-152b-4bb5- a2c6-3e05b2365c04; TransactionId = 1a11130e-e8dd-4fa1-9107-3b46dcb4ffd6; HandlerName = GroupCreatedNotificationHandler; HandlerId = WORKDEVELOPMENT.1)将工具'0967e031-398f-437d-8949-2a17fe844df0'的事件推送到 http://tpidev.pearsoncmg. com/tpi/lti/service/event ...

[2011-12-15 16:27:21,259] [DEBUG] [TPI.LTI.Facades.LTIFacade:TPI.LTI.Provisioning.Handlers.GroupCreatedNotificationHandler.WORKDEVELOPMENT.1_Thread:299] :( ContextId = 184e82dd-152b-4bb5- a2c6-3e05b2365c04; TransactionId = 1a11130e-e8dd-4fa1-9107-3b46dcb4ffd6; HandlerName = GroupCreatedNotificationHandler; HandlerId …

c# multithreading thread-safety threadstatic c#-4.0

5
推荐指数
1
解决办法
2034
查看次数

线程静态,ASP.NET和异步处理程序

请考虑这些sceanrios:

  1. 异步.ashx处理程序
  2. 异步.asmx Web服务方法
  3. 同步MVC 5控制器动作方法

我试图找出一种方法来设置"逻辑"特定数据,这些数据可以在"逻辑"http请求期间一致地访问,即,如果数据是在"BeginExecute"部分中的线程中设置的,那么该异步处理程序您会考虑,即使ASP.NET在不同的OS/.Net线程上执行"EndExecute"部分,该数据也可以在该asnc处理程序的"EndExecute"部分中使用.

此外,我希望在第二个请求被分配给先前分配给第一个http请求的线程的时候,在随后的http请求中,在"BeginExecute"部分中设置的任何OS/.Net线程中的数据都不可用.它位于"BeginExecute"部分,但是当第一个http请求进入异步操作时,该线程被释放(并且它可能仍在完成其异步操作).

我相信.Net中的"逻辑线程"或"逻辑线程上下文"这个词实际上意味着我提到的相同的"逻辑"操作流程(而不是继续重新分配的底层OS/.Net线程).如果从工作流角度来看,每个http请求都是一个新的"逻辑"操作(即使多个用户按顺序或并行调用相同的Web服务,每个请求都是一个新的和部分逻辑操作),并且在此意思是,"逻辑"操作是一次性的,不能重复.但是,相同的底层OS/.Net线程可以根据其可用性到达时映射到"逻辑"操作.

另外,我想将此数据公开为HttpContext.Current类的静态属性.对于某些人来说,这可能会让人感到意外,但如果您使用的是异步.asmx Web服务方法,则HttpContext.Current无法正常工作.我确信我已经阅读了网上的内容,其中说HttpContext.Current应该总是返回正确的HttpContext,但我在.asmx web-methods的EndExecuteMethod中看到它为null.如果有人可以确认我是否正确地做出我的最后陈述,那将是很好的,但这个陈述不是我试图在这里提出的整体问题.

在阅读了大量文献后(例如log4net.ThreadContext和log4net.LogicalThreadContext之间有什么区别?,http://msmvps.com/blogs/jon_skeet/archive/2010/11/08/the-importance-of-context -and-a-question-of-explicitness.aspx,http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html以及更多包括MSDN文档),以下是我的推论:

  1. ThreadStatic是底层OS/.Net线程的本地,而不是"逻辑"操作,因此在我的例子中; 如果第二个http请求被分配了与第一个线程的"BeginExecute"相同的线程,则在"BeginExecute"中的第一个http请求中设置的数据将在下一个http请求中可见.如果它恰好被.Net重新分配给另一个线程,那么这个数据在"EndExecute"中将不可用(在绝大多数情况下会发生这种情况).
  2. 对于我的用例,Thread.SetData甚至更成问题.它需要传入数据槽,如果我从Thread.GetNamedDataSlot的返回值传入数据槽,则该信息可在app域中获得; 由于命名数据​​槽在线程之间共享.
  3. CallContext.SetData类似于ThreadStatic(这意味着它不被app域共享,但是如果它们被分配到相同的底层OS/.Net线程,则不同的http请求将看到相同的数据).CallContext.SetData提供了一个额外的能力来编组RPC调用的上下文数据,这与当前提出的问题无关.
  4. 然后是ThreadLocal类(.Net 4/.Net 4.5).它本来可以解决我问题的一部分,我可以在BeingExecute操作的stateObject中传递它,并从endExecute操作的相同stateObject参数中提取.从这个角度来看,ThreadLocal似乎是为.Net的异步支持编写的.但是当我需要像HttpContext.Current那样访问它时它将无法工作,因为我无法看到保留"逻辑线程静态"实例(除非我在之前的3分中说错了).
  5. 最后似乎CallContext.LogicalSetData做了我打算实现的目标.使用CallContext.LogicalSetData和CallContext.LogicalGetData方法的集合,我应该能够实现HttpContext.Current这样的影响,它可以正常地用于"逻辑任务执行".

现在来问题:

  1. 我上面说的一切都是正确的.请更正我所做的任何和所有不正确的声明.
  2. 我错过了什么其他选项可用于.Net中的线程静态类功能.
  3. CallContext.LogicalSetData/LogicalGetData是否将上下文数据传递给RPC调用(msdn页面没有明确提及,http://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.callcontext.logicalsetdata (v = vs.110).aspx).
  4. 使用CallContext.LogicalSetData/LogicalGetData是否有任何缺点(性能明智或其他方面).
  5. 本页介绍了LogicalSetData的写时复制行为:http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html.在异步处理程序/异步MVC 5操作方法的上下文中,如果使用logicalsetdata保存引用类型并稍后更改引用类型的状态会产生什么影响.什么是复发.
  6. 对于mutation/logicalsetdata/async,我仍然无法通过改变对象来看出问题是什么.当异步方法启动时,写入时复制行为将在下次调用logicalsetdata时触发上下文数据的副本.这是一个浅层副本,因此我的参考对象现在实际上由2个逻辑上下文共享,并且在另一个上下文中的更改在我通常期望的引用类型中是可见的.

一个很长的问题,有很多参考文献,但希望我做得很好,答案也会让其他人受益.

c# asp.net multithreading asynchronous threadstatic

5
推荐指数
1
解决办法
1147
查看次数

ThreadStatic的C#Singleton模式设计

我想弄清楚单身模式设计.我想从我的单例类为每个线程创建单独的实例.所以我在下面提供了两个设计.

这是工作

class Program
{
    static void Main(string[] args)
    {
        Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
        Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
        Console.ReadLine();
    }
}
public sealed class SingletonClass
{
    [ThreadStatic]
    private static SingletonClass _instance;

    public static SingletonClass Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new SingletonClass();
            }
            return _instance;
        }
    }
    private SingletonClass()
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

它不起作用(抛出NullReferenceException并且没有创建实例.)

class Program
{
    static void Main(string[] args)
    {
        Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
        Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
        Console.ReadLine();
    }
}
public sealed class SingletonClass
{
    [ThreadStatic]
    private …
Run Code Online (Sandbox Code Playgroud)

c# singleton multithreading singleton-methods threadstatic

5
推荐指数
1
解决办法
599
查看次数

异步ASP.NET Web API中的ThreadStatic

是否有可能在单个请求中使用线程静态变量?当前代码使用线程静态变量进行日志记录,现在我们希望使用异步控制器方法(使用async和await模式),这会导致问题,因为在打开新线程时该变量为null.

asp.net threadstatic async-await asp.net-web-api requestscope

4
推荐指数
1
解决办法
833
查看次数

如何在C#中跨异步等待模型维护线程上下文?

每次等待完成"选项"时,是否正在使用ThreadStatic并设置上下文?还有另外一种方法吗?

public async void Test()
{
    // This is in Thread 1
    Foo foo = new Foo();
    Context.context = "context1"; // This is ThreadStatic
    string result = await foo.CallAsynx();

    // This is most likely Thread 2
    Context.context = "context1";   // This might be a different thread and so resetting context    
}
Run Code Online (Sandbox Code Playgroud)

如果我不想使用ThreadStatic,现在有另一种方法吗?

c# threadstatic async-await

3
推荐指数
2
解决办法
5505
查看次数

使用[ThreadStatic]是否与异步代码不一致?

我们有一个相当大的现有代码库,用于构建在ASP.NET之上的各种web服务,并且该代码大量使用访问HttpContext.Current.User(包装为Client.User),我相当确定内部使用它[ThreadStatic]来为您提供环境范围.

我目前正在研究是否有可能我们开始以形式使用更多的异步代码,async/await但我很难找到如何使用[ThreadStatic]它.[ThreadStatic]由于其大量使用,实际上不可能消除对依赖的依赖.

我的理解是,当await命中时,代码的执行在那里停止,调用立即返回,并且设置延续以在异步代码返回时继续执行.同时,原始线程可以自由地用于其他事情,例如处理另一个请求.到目前为止我对它的理解.

我无法真正找到一个确定的答案HttpContext.Current.User是,在之前和之后是否保证是相同的await.

所以基本上:

HttpContext.Current.User = new MyPrincipal();
var user = HttpContext.Current.User;

await Task.Delay(30000);

// Meanwhile, while we wait for that lots of other requests are being handled, 
// possibly by this thread.

Debug.Assert(object.ReferenceEquals(HttpContext.Current.User, user));
Run Code Online (Sandbox Code Playgroud)

这有Debug.Assert保证会成功吗?

如果另一个请求由与Task.Delay挂起的相同的线程处理,那么该请求将设置一个不同的HttpContext.Current.User,那么在调用continuation时以某种方式存储和恢复的先前状态是什么?


我可以想象的是,在幕后,[ThreadStatic]状态被保存为线程本身的某种字典,并且当一个线程返回到线程池后返回await该字典时,该字典在某处保持安全并且在设置回线程时它执行延续(或者在一个线程上,我不确定它是否一定是处理延续的同一个线程),可能是对屁股的鼓励和"去得到他们的男孩!",但最后部分可能只是我的想象力.

这有点准确吗?

更新:我试图将一个小试验放在一起尝试这个.到目前为止它似乎工作,并且断言没有因为数百个请求中的任何一个而失败.谁能验证测试是否有意义?

https://gist.github.com/anonymous/72d0d6f5ac04babab7b6

c# asynchronous threadstatic async-await

3
推荐指数
1
解决办法
1196
查看次数