2011-08-01 4 views
14

TPL 작업에서 ThreadStatic과 같은 것을 어떻게 사용할 수 있습니까? 내 이해 ("C#으로 Wrox Professional 병렬 프로그래밍", p74)은 작업이 실행 중에 한 스레드에서 다른 스레드로 전환 할 수 있다는 것입니다.ThreadStatic for TPL 작업

내가 원하는 것을 원하십니까?

이 ID를 모든 메서드에 전달할 필요가 없도록 정적 클래스 내에 세션 ID를 유지하려고합니다. 내 라이브러리에는 login(id), logout(id)과 같은 메서드가 있으며이 ID와 연결된 자격 증명을 처리하는 여러 메서드가 있습니다. 그러나 나는 모든 사람에게이 이드를 전달하고 싶지 않다. 내 라이브러리가 다른 세션에서 다른 스레드 내에서 호출되도록 할 수 있습니다. 따라서 login()의 ID를 ThreadStatic 변수에 저장하면됩니다.

이제는 나를 위해 생성 된 TPL 작업을 ThreadPool으로 사용하고 싶습니다. 내 세션 ID를 작업에 전달할 수 있지만이 ID를 ThreadStatic 변수에 저장하면 내 작업이 스레드를 전환해도 생존하지 못합니다.

+2

. 그걸 가능성에 대해 어디서 들었습니까? –

+2

"C#을 사용하는 Wrox Professional 병렬 프로그래밍"책의 74 페이지에 그림이 있으며 작업자 스레드 간의 작업 전환을 보여줍니다. – Gerard

+1

@Gerard : 한 스레드에 대해 * 대기열에 들어가는 작업보다는 * 실행 중 *인지 확인한 다음 실행을 위해 다른 스레드로 전환한다는 의미의 도용이 있습니까? –

답변

1

올바른지, thread-static은 작업에 적합하지 않습니다.

매개 변수 전달과 관련된 문제를 해결하는 것이 더 낫습니다. 그냥 지나치게 더 깨끗하고 깨끗합니다. 약간의 타이핑은 당신에게 훨씬 더 가독성과 스레드 안전성을 가져다 줄 것입니다.

+0

감사합니다. 그게 내가 두려워하는 것. 많은 수준의 기능을 많이 호출해야합니다. 실제로 모든 함수에는 세션 ID 매개 변수가 필요합니다. 이 문제를 해결하기위한 다른 아이디어는 없습니까? – Gerard

2

어떤 스레드에서 실행되는 작업에 대한 보장이 없다면 정적 스레드를 피하는 것이 좋습니다. 그냥 지나쳐. 당신의 의도는 더 분명해질 것입니다.

4

TPL 당신은 훨씬 당신이 ThreadStatic를 사용하는 것과 같은 방법을 CallContext.LogicalSetData(string, object)CallContext.GetLogicalData(string)를 사용할 수 있다는 것을 의미 닷넷 4.5의 비동기 흐름 ExecutionContext. 그러나 상당한 성능 저하가 발생합니다.

더 깊은 다이빙을 위해서는 Async Causality Chain Tracking, How to include own data in ExecutionContextExecutionContext vs SynchronizationContext을 참조하십시오.

사용 예 :

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 
관련 문제