ExecutionContext of Threads
Asked Answered
E

4

13

What's the purpose of ExecutionContext.SuppressFlow();? In the following code what exactly gets suppressed?

I've this test code...

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/>";
         }
      }
   }
}
Esdraelon answered 23/12, 2009 at 10:22 Comment(4)
HI, so i got here also trying to understand more, in your journey so far do you know how this is "threadsafe" when ExecutionContext.SuppressFlow(); is called how do you control which thread are globally affected. surely it would need a lock of sorts, im looking at github.com/dotnet/runtime/blob/… and dont see any locks, but ExecutionContext.SuppressFlow(); is application wide correct surely this would mean that while disabled any threads created in that moment would be ?Ellissa
i thnk i found the answer i was lookng for its on the current thread... flowEllissa
ooo the answer to yours is then related to 'Thread.CurrentThread.CurrentCulture' as its changing the Culture which is linked to the thread... my understanding is by using ExecutionContext.SuppressFlow(); in this its saying dont trying and change the parent threads Culture as well .... or something like thatEllissa
stop copying/flowing main thread context data structure to child thread(helperthread) more performance gain at server side program. afaiu.wordpress.com/2012/07/01/net-tips-and-quick-reference-2Ellissa
L
12

The details of ExecutionContext are very obscure, buried deep inside features like .NET Remoting and WCF. What is part of it is:

  • HostExecutionContext
  • IllogicalCallContext, a repository of thread specific data used by Remoting
  • LogicalContext, as above
  • SecurityContext
  • SynchronizationContext

CultureInfo is not part of it, which can be a considerable problem if you change your main thread's default culture. There is no good way to ensure other threads run with that culture unless you explicitly write the code to switch them. That's not always practical, given that .NET is apt to run async callbacks on threadpool threads. They will be initialized to the system default culture.

Edit: this problem got fixed in .NET 4.5 with the CultureInfo.DefaultThreadCurrentCulture property.

Edit2: fixed much more thoroughly in .NET 4.6, culture now flows as expected.

Luxuriance answered 23/12, 2009 at 11:8 Comment(9)
It's written in App Development Foundation book that, "By default, the execution context flows to helper threads, but it does so at a cost. If you want to stop the flow of context information (increasing performance but losing the current security, CULTURE, and transaction context information), you can use the ExecutionContext class.", @nobugz: Could you kindly explain this??Esdraelon
Culture means such information as the current thread language, currency or number representation, etc.Djebel
@serhio: Yes and this is contain in CultureInfo so this means if we suppress and change the culture it'll not get forwarded to threads being created in this scope?? and if we don't suppress it'll pass through the helper threads?? In the above code, however, whether I suppress or not, the threads culture is alwasy en-US, which is machine default.Esdraelon
The book is wrong, as you found out. "Cost" is nonsense too, burn the book.Luxuriance
@kamran... I got a look on the internal structure of the ExecutionContext, there really no indication of presence of a culture inforamtion. But... What is your problem? Culture, which is indicated by the Thread.CurrentCulture property, corresponds by default to the selection in Regional Options in the control panel. This affects how numbers, dates, and times are formatted. UICulture, indicated by the Thread.CurrentUICulture property, corresponds by default to the language of the OS, or the selected language on a multi-language Windows.Djebel
@serhio: dosen't this corresponds to the creating (main) thread culture. By default the helper threads takes the culture of the creating thread. In the code above before creating the helper threads I changed the culture of the main thread to en:GB and the helper still gets en-US even if I don't suppress.Esdraelon
so, look, may be I'm missing out some thing here. For which I wanted an explanation.Esdraelon
Erm, you got one. CultureInfo is not part of ExecutionContext. What is still unclear?Luxuriance
Where exactly is this ExecutionContext data structure within the thread? Does it reside within the thread's Thread Environment Block (TEB) or thread's kernel object?Deterrence
D
12

ExcecutionContext.SuppressFlow suppresses the flow of the execution context across asynchronous threads.

The ExecutionContext, are implicitly passed from parent thread to the child one, provides information relevant to a logical thread of execution: security context, call context and synchronization context. If that information is not imperative, the omission of the execution context optimize a little the performance of a multithreading application.

ExecutionContext.RestoreFlow restores the passage of the execution context between threads.

Finally

Q: In the following code what exactly gets suppressed??

A: Exactly are suppressed the passage of the following information: security context, call context and synchronization context; between the newly created threads. Why that was do? -To optimize the creation and work of th.Length created threads: less supplementary information passed between threads - quicker this threads interact between them.

Djebel answered 23/12, 2009 at 10:35 Comment(1)
Well my Q's was not exactly this... This is a kind of technical jargon we got to read in each article. I've presented some code above and with respect to that I wanted to be enlighted what exactly got suppressed in above code..Esdraelon
L
12

The details of ExecutionContext are very obscure, buried deep inside features like .NET Remoting and WCF. What is part of it is:

  • HostExecutionContext
  • IllogicalCallContext, a repository of thread specific data used by Remoting
  • LogicalContext, as above
  • SecurityContext
  • SynchronizationContext

CultureInfo is not part of it, which can be a considerable problem if you change your main thread's default culture. There is no good way to ensure other threads run with that culture unless you explicitly write the code to switch them. That's not always practical, given that .NET is apt to run async callbacks on threadpool threads. They will be initialized to the system default culture.

Edit: this problem got fixed in .NET 4.5 with the CultureInfo.DefaultThreadCurrentCulture property.

Edit2: fixed much more thoroughly in .NET 4.6, culture now flows as expected.

Luxuriance answered 23/12, 2009 at 11:8 Comment(9)
It's written in App Development Foundation book that, "By default, the execution context flows to helper threads, but it does so at a cost. If you want to stop the flow of context information (increasing performance but losing the current security, CULTURE, and transaction context information), you can use the ExecutionContext class.", @nobugz: Could you kindly explain this??Esdraelon
Culture means such information as the current thread language, currency or number representation, etc.Djebel
@serhio: Yes and this is contain in CultureInfo so this means if we suppress and change the culture it'll not get forwarded to threads being created in this scope?? and if we don't suppress it'll pass through the helper threads?? In the above code, however, whether I suppress or not, the threads culture is alwasy en-US, which is machine default.Esdraelon
The book is wrong, as you found out. "Cost" is nonsense too, burn the book.Luxuriance
@kamran... I got a look on the internal structure of the ExecutionContext, there really no indication of presence of a culture inforamtion. But... What is your problem? Culture, which is indicated by the Thread.CurrentCulture property, corresponds by default to the selection in Regional Options in the control panel. This affects how numbers, dates, and times are formatted. UICulture, indicated by the Thread.CurrentUICulture property, corresponds by default to the language of the OS, or the selected language on a multi-language Windows.Djebel
@serhio: dosen't this corresponds to the creating (main) thread culture. By default the helper threads takes the culture of the creating thread. In the code above before creating the helper threads I changed the culture of the main thread to en:GB and the helper still gets en-US even if I don't suppress.Esdraelon
so, look, may be I'm missing out some thing here. For which I wanted an explanation.Esdraelon
Erm, you got one. CultureInfo is not part of ExecutionContext. What is still unclear?Luxuriance
Where exactly is this ExecutionContext data structure within the thread? Does it reside within the thread's Thread Environment Block (TEB) or thread's kernel object?Deterrence
G
2

Not the answer to your question, but since you're looking at this code and try to understand it right now, please check if you want to adapt/change your code according to the documentation (i.e. "fix it"):

ExecutionContext.SuppressFlow:

You must use the Undo method on the returned AsyncFlowControl structure to restore the flow of the ExecutionContext.

ExecutionContext.RestoreFlow:

RestoreFlow reverses the effect of a prior SuppressFlow method call.

This method is called by the Undo method of the AsyncFlowControl structure returned by the SuppressFlow method. You should use the Undo method to restore the flow of the execution context, not the RestoreFlow method.

Emphasis mine.

Gombroon answered 23/12, 2009 at 10:58 Comment(1)
@Benjamin Podszun: ExecutionContext.RestoreFlow; is also valid. Though Undo is preferred..Esdraelon
C
2

I read this - "When a thread is created, the runtime ensures that the initiating thread’s execution context is flowed to the new thread. This way the new thread has the same privileges as the parent thread. This copying of data does cost some resources, however. If you don’t need this data, you can disable this behavior by using the ExecutionContext.SuppressFlow method."

Source : Programming in C# Exam 70-483. Author : Wouter de Kort

You would call ExecutionContext.SuppressFlow() to improve performance by reducing execution time of the application as the method call will prevent copying of context data from parent thread to the child thread that would otherwise impact or increase the execution time when you may not require the context data of the parent thread in the child thread.

Cubical answered 18/3, 2016 at 15:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.