线程的ExecutionContext
ExecutionContext.SuppressFlow();
的目的是什么? ? 在下面的代码中究竟被压制了什么?
我有这个测试代码……
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 + "
"; } } } }
ExecutionContext的细节非常模糊,深埋在.NET Remoting和WCF等function中。 它的一部分是:
- HostExecutionContext
- IllogicalCallContext,Remoting使用的线程特定数据的存储库
- LogicalContext,如上所述
- SecurityContext的
- 的SynchronizationContext
CultureInfo不是它的一部分,如果你改变主线程的默认文化,这可能是一个相当大的问题。 除非您明确编写代码来切换它们,否则没有好办法确保其他线程与该文化一起运行。 鉴于.NET易于在线程池线程上运行异步回调,这并不总是实用的。 它们将初始化为系统默认文化。
编辑:使用CultureInfo.DefaultThreadCurrentCulture属性在.NET 4.5中修复此问题。
Edit2:在.NET 4.6中更加彻底地修复,文化现在按预期流动。
ExcecutionContext。 SuppressFlow禁止跨异步线程执行上下文的流。
ExecutionContext被隐式地从父线程传递给子线程,提供与逻辑执行线程相关的信息:安全上下文,调用上下文和同步上下文。 如果该信息不是必需的,则省略执行上下文会优化multithreading应用程序的性能。
执行上下文。 RestoreFlow恢复线程之间执行上下文的传递 。
最后
问 : 在下面的代码中究竟被压制了什么?
答 :完全抑制了以下信息的传递:安全上下文,调用上下文和同步上下文; 在新创建的线程之间。 为什么那样呢? – 优化th.Length创建的线程的创建和工作:线程之间传递的补充信息更少 – 这些线程在它们之间交互的速度更快。
不是你的问题的答案,但既然你正在查看这段代码并试着立即理解它,请检查你是否要根据文档调整/更改你的代码(即“修复它”):
ExecutionContext.SuppressFlow:
必须在返回的AsyncFlowControl结构上使用Undo方法来恢复ExecutionContext的流。
ExecutionContext.RestoreFlow:
RestoreFlow反转先前SuppressFlow方法调用的效果。
此方法由SuppressFlow方法返回的AsyncFlowControl结构的Undo方法调用。 您应该使用Undo方法来恢复执行上下文的流,而不是RestoreFlow方法。
强调我的。
我读到这个 - “当创建一个线程时,运行时确保启动线程的执行上下文流到新线程。这样新线程具有与父线程相同的权限。这种数据复制确实需要一些资源,但是。如果您不需要此数据,可以使用ExecutionContext.SuppressFlow方法禁用此行为。“
资料来源:C#考试编程70-483。 作者:Wouter de Kort
创建线程时,运行时会确保启动线程的执行上下文流向新线程。 这样,新线程具有与父线程相同的权限。 然而,这种数据复制确实需要花费一些资源。 如果您不需要此数据,则可以使用ExecutionContext.SuppressFlow方法禁用此行为。