gpt4 book ai didi

c# - SynchronizationContext 有什么作用?

转载 作者:IT王子 更新时间:2023-10-29 03:35:28 30 4
gpt4 key购买 nike

在Programming C#一书中,它有一些关于SynchronizationContext的示例代码。 :

SynchronizationContext originalContext = SynchronizationContext.Current;
ThreadPool.QueueUserWorkItem(delegate {
string text = File.ReadAllText(@"c:\temp\log.txt");
originalContext.Post(delegate {
myTextBox.Text = text;
}, null);
});

我是线程的初学者,所以请详细回答。
首先,我不知道context是什么意思,程序保存在 originalContext中是什么意思? ?而当 Post方法被触发,UI 线程会做什么?
如果我问了一些愚蠢的事情,请纠正我,谢谢!

编辑:例如,如果我只写 myTextBox.Text = text; 呢?在方法上,有什么区别?

最佳答案

What does SynchronizationContext do?


简单地说, SynchronizationContext 表示可能会执行代码的“位置”。传递给其 Send 的委托(delegate)或 Post method然后将在该位置调用。 ( PostSend 的非阻塞/异步版本。)
每个线程都可以有一个 SynchronizationContext与之关联的实例。正在运行的线程可以通过调用 static SynchronizationContext.SetSynchronizationContext method 与同步上下文相关联。 , 并且可以通过 SynchronizationContext.Current property 查询正在运行的线程的当前上下文.
尽管我刚刚写了什么(每个线程都有一个关联的同步上下文),一个 SynchronizationContext不一定代表特定的线程;它还可以将传递给它的委托(delegate)的调用转发到几个线程中的任何一个(例如到 ThreadPool 工作线程),或(至少在理论上)到特定的 CPU 内核,甚至到另一个网络主机。您的代表最终在哪里运行取决于 SynchronizationContext 的类型用过的。
Windows 窗体将安装 WindowsFormsSynchronizationContext在创建第一个表单的线程上。 (这个线程通常被称为“UI 线程”。)这种类型的同步上下文正是在那个线程上调用传递给它的委托(delegate)。这非常有用,因为 Windows 窗体与许多其他 UI 框架一样,只允许在创建它们的同一线程上操作控件。

What if I just write myTextBox.Text = text; in the method, what's the difference?


您传递给 ThreadPool.QueueUserWorkItem 的代码将在线程池工作线程上运行。也就是说,它不会在你的 myTextBox 所在的线程上执行。已创建,因此 Windows 窗体迟早会(尤其是在发布版本中)抛出异常,告诉您可能无法访问 myTextBox从另一个线程。
这就是为什么您必须在该特定分配之前以某种方式从工作线程“切换回”到“UI 线程”(创建 myTextBox 的地方)。这是按如下方式完成的:
  • 当您仍在 UI 线程上时,捕获 Windows 窗体的 SynchronizationContext在那里,并将对它的引用存储在变量 ( originalContext ) 中以备后用。您必须查询SynchronizationContext.Current这一点;如果您在传递给 ThreadPool.QueueUserWorkItem 的代码中查询它,您可能会获得与线程池的工作线程相关联的任何同步上下文。一旦您存储了对 Windows 窗体上下文的引用,您就可以随时随地使用它来将代码“发送”到 UI 线程。
  • 每当您需要操作 UI 元素(但不再或可能不再在 UI 线程上)时,请通过 originalContext 访问 Windows 窗体的同步上下文。 ,并将操作 UI 的代码移交给 SendPost .

  • 最后的评论和提示:
  • 同步上下文不会告诉您哪些代码必须在特定位置/上下文中运行,哪些代码可以正常执行,而无需将其传递给 SynchronizationContext .为了做出决定,您必须了解您编程所针对的框架的规则和要求 — 在本例中为 Windows 窗体。
    因此,请记住 Windows 窗体的这条简单规则:不要从创建它们的线程以外的线程访问控件或窗体。如果您必须这样做,请使用 SynchronizationContext如上所述的机制,或 Control.BeginInvoke (这是执行完全相同的事情的特定于 Windows 窗体的方式)。
  • 如果您针对 .NET 4.5 或更高版本进行编程,则可以通过转换显式使用 SynchronizationContext 的代码使您的生活更轻松。 , ThreadPool.QueueUserWorkItem , control.BeginInvoke等交给新的 async / await keywordsTask Parallel Library (TPL) ,即围绕 Task 的 API和 Task<TResult> 类。这些将在很大程度上负责捕获 UI 线程的同步上下文,启动异步操作,然后返回到 UI 线程,以便您可以处理操作的结果。
  • 关于c# - SynchronizationContext 有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18097471/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com