ThreadStatic的第三方物流任务 [英] ThreadStatic for TPL Task

查看:113
本文介绍了ThreadStatic的第三方物流任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何能像一个<一个href="http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx"><$c$c>ThreadStatic在TPL任务中使用?我的理解(Wrox的专业并行程序设计与C#,P74)是一个任务可以从一个线程在执行过程中切换到另一个。

How can something like a ThreadStatic be used in a TPL Task? My understanding ("Wrox Professional Parallel Programming with C#", p74) is that a Task can switch from one thread to another during execution.

我想做的事情是什么?

我要保持一个会话ID内的静态类,所以我不需要这个ID传递给我所有的方法。我的图书馆有一个像登录(ID)注销(ID)并在与此相关的凭证经营方法很多方法ID。但我不希望这个ID传递给每一个方法。我可以确保我的图书馆被称为不同的线程中对不同的会话。所以节省了ID里面 ThreadStatic 变量将工作登录()

I want to maintain a session id inside a static class so I don't need to pass this id to all of my methods. My library has methods like login(id), logout(id) and many methods which operate on credentials associated with this id. But I don't want to pass this id to every method. I can make sure my library is called within different thread for different sessions. So saving the id inside login() in a ThreadStatic variable will work.

现在我想用这对我来说是一个线程池创建TPL任务。我可以通过我的会话ID的任务,但如果我保存这个ID的 ThreadStatic 变量中,如果我的任务切换线程就无法生存。

Now I want to use TPL Tasks which are created for me by a ThreadPool. I can pass my session id to the Task, but if I store this id inside a ThreadStatic variable it will not survive if my Task switches threads.

推荐答案

TPL和.NET 4.5的异步流执行上下文,这意味着您可以使用 CallContext.LogicalSetData(字符串对象) CallContext.GetLogicalData(字符串)的多,你会用同样的方法 ThreadStatic 。但它确实招致显著的性能损失。

TPL and .Net 4.5's async flow the ExecutionContext, which means you can use CallContext.LogicalSetData(string, object) and CallContext.GetLogicalData(string) in much the same way you would use ThreadStatic. It does incur a significant performance penalty, however.

请参阅异步因果链跟踪,的如何纳入ExecutionContext中自己的数据,和<一href="http://blogs.msdn.com/b/pfxteam/archive/2012/06/15/executioncontext-vs-synchronizationcontext.aspx"相对=nofollow>执行上下文VS的SynchronizationContext 进行更深层次的跳水。

See Async Causality Chain Tracking, How to include own data in ExecutionContext, and ExecutionContext vs SynchronizationContext for a deeper dive.

使用示例:

class Program
{
    static void Main(string[] args)
    {
        Logger.Current = new Logger("Test Printer");

        Logger.Current.Print("hello from main");
        var t1 = Task.Run(() => { Logger.Current.Print("hello from thread " + Thread.CurrentThread.ManagedThreadId); });
        var t2 = Task.Run(() => { Logger.Current.Print("hello from thread " + Thread.CurrentThread.ManagedThreadId); });
        Task.WaitAll(t1, t2);
    }
}

class Logger
{
    private string LogName;

    public Logger(string logName)
    {
        if (logName == null)
            throw new InvalidOperationException();

        this.LogName = logName;
    }

    public void Print(string text)
    {
        Console.WriteLine(LogName + ": " + text);
    }

    public static Logger Current
    {
        get
        {
            return CallContext.LogicalGetData("PrinterName") as Logger;
        }
        set
        {
            CallContext.LogicalSetData("PrinterName", value);
        }
    }
}

打印:


Test Printer: hello from main  
Test Printer: hello from thread 11 
Test Printer: hello from thread 10

这篇关于ThreadStatic的第三方物流任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆