2009-12-23 19 views
7

ExecutionContext.SuppressFlow();的用途是什麼?在下面的代碼究竟是什麼被壓制?線程的ExecutionContext

我有這個測試代碼...

protected void btnSubmit_Click(object sender, EventArgs e) 
{ 
    Thread[] th = new Thread[100]; 
    Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-GB"); 

    AsyncFlowControl cntrl = ExecutionContext.SuppressFlow(); 
    for (int i = 0; i < th.Length; i++) 
    {     
     th[i] = new Thread(new ParameterizedThreadStart(ThreadMethod)); 
     th[i].Name = "Thread #" + (i+1).ToString();     
     th[i].Start((i+1).ToString()); 
    } 
    ExecutionContext.RestoreFlow(); 

    foreach (Thread t in th)    
    { 
     t.Join(); 
    } 
    Response.Write(response); 
} 


String response = null; 
Random rnd = new Random(1000); 
private void ThreadMethod(object param) 
{ 
    if (param != null) 
    { 
     string temp = param as string; 
     if (temp != null) 
     { 
     //To test what is the current culture I get for this thread execution 
     System.Globalization.CultureInfo info = Thread.CurrentThread.CurrentCulture; 
     for (int i = 0; i <= 10; i++) 
     { 
      Thread.Sleep(rnd.Next(2000)); 
      response += Thread.CurrentThread.ManagedThreadId.ToString() + ":" 
        + Thread.CurrentThread.Name + ": " + temp + "<br/>"; 
     } 
     } 
    } 
} 

回答

8

ExecutionContext的細節非常模糊,隱藏在.NET Remoting和WCF等深層功能中。 這是它的一部分是:

  • HostExecutionContext
  • IllogicalCallContext,通過遠程處理
  • LogicalContext使用線程特定數據的儲存庫,如上面
  • SecurityContext的
  • 的SynchronizationContext

CultureInfo不是它的一部分,如果你改變你的話,這可能是一個相當大的問題ain線程的默認文化。除非您明確寫入代碼來切換它們,否則沒有好的方法可以確保其他線程能夠使用該文化。這並不總是實際的,因爲.NET可以在線程池線程上運行異步回調。他們將被初始化爲系統默認文化。

編輯:此問題已在.NET 4.5中用CultureInfo.DefaultThreadCurrentCulture屬性修復。編輯2:在.NET 4.6中進行了更徹底的修正,文化現在按預期流動。

+0

它是在應用程序開發基金會書中寫道:「默認情況下,執行上下文流向助手線程,但它是這樣做的代價,如果你想停止上下文信息的流動(提高性能,但丟失當前安全性,CULTURE和事務上下文信息),則可以使用ExecutionContext類。「,** @ nobugz:**您能否解釋一下? – 2009-12-23 11:26:13

+0

*文化*是指當前線程語言,貨幣或數字表示等信息 – serhio 2009-12-23 11:38:16

+0

** @ serhio:**是的,這包含在CultureInfo中,所以這意味着如果我們壓制和改變它不會得到的文化轉發給在此範圍內創建的線程?如果我們不壓制它會通過幫助線程?但是,在上面的代碼中,不管我是否抑制,線程文化都是機器默認的en-US。 – 2009-12-23 11:45:48

6

ExcecutionContext。 SuppressFlow可以抑制執行上下文跨異步線程的流程。

ExecutionContext隱式地從父線程傳遞到子線程,提供與邏輯執行線程相關的信息:安全上下文,調用上下文和同步上下文。如果這些信息不是強制性的,那麼執行上下文的省略會優化多線程應用程序的性能。

ExecutionContext。 RestoreFlow恢復線程之間執行上下文的通道。

最後

Q在下面的代碼究竟被抑制?

A:確實被壓制通過以下信息:安全上下文,調用上下文和同步上下文;在新創建的線程之間。 爲什麼那是嗎? - 優化創建和工作創建的線程:在線程之間傳遞較少的補充信息 - 這些線程更快地在它們之間進行交互。

+0

那麼我的Q不完全是這個...這是我們在每篇文章中讀到的一種技術術語。我已經提出了一些上面的代碼,並且相對於我想要明白的是在上面的代碼中抑制了什麼。 – 2009-12-23 10:46:31

+0

@S M Karman:請參閱我的編輯。 – serhio 2009-12-23 10:59:10

1

不是您的問題的答案,但是因爲您正在查看此代碼並嘗試瞭解它,請檢查您是否要根據文檔修改/更改代碼(即「修復」) :

ExecutionContext.SuppressFlow:

必須使用對返回AsyncFlowControl結構Undo方法來恢復執行上下文的流動。

ExecutionContext.RestoreFlow:

RestoreFlow反轉現有SuppressFlow方法調用的效果。

該方法由SuppressFlow方法返回的AsyncFlowControl結構的Undo方法調用。 您應該使用Undo方法來恢復執行上下文的流動,而不是RestoreFlow方法。

強調我的。

+0

** @ Benjamin Podszun:** ExecutionContext.RestoreFlow;也是有效的。雖然撤消是首選.. – 2009-12-23 11:23:43

1

我讀過 - 「創建線程時,運行時確保啓動線程的執行上下文流向新線程,這樣新線程具有與父線程相同的權限 這種數據拷貝但是如果你不需要這些數據,你可以通過使用ExecutionContext.SuppressFlow方法來禁止這種行爲。

來源:C#Exam 70-483編程。作者:Wouter de Kort

+0

您可以通過減少應用程序的執行時間來調用ExecutionContext.SuppressFlow()來提高性能,因爲方法調用會阻止將上下文數據從父線程複製到子線程,否則這些子線程可能會影響或增加執行時間子線程中父線程的上下文數據。 – 2016-06-12 10:02:50

0

當創建線程時,運行時確保發起線程的執行上下文流到新線程。這樣新線程就具有與父線程相同的權限。但是,這種數據拷貝確實會花費一些資源。如果您不需要此數據,則可以使用ExecutionContext.SuppressFlow方法禁用此行爲。

相關問題