更多 C# 事件和线程安全

Posted

技术标签:

【中文标题】更多 C# 事件和线程安全【英文标题】:More C# Events and Thread Safety 【发布时间】:2022-01-14 03:28:02 【问题描述】:

我读了C# Events and Thread Safety 以及MSDN

中的线程安全委托调用部分

在问问题之前,我定义线程安全,有三个方面:

    (item1) 无错误数据 R/W。 (中间数据) (item2)指令重编没有影响。 (item3)缓存一致性没有影响。

让我们再看一下这个例子:

PropertyChanged?.Invoke(…)

var handler = this.PropertyChanged;
if (handler != null)

    handler(…);

好的,在 C# 中,引用类型的 R/W OP 不是坏数据问题。因此,当调用处理程序时,它永远不会为空。 但是,我还有疑问

    C#底层是否有机制保证一个联锁的API操作实际应用到PropertyChanged,所以指令重排序不会有问题缓存一致性。 如果确实有类似的互锁机制,是不是只针对委托和事件类型?对于可以使用的其他变量类型是否有这样的保证。?运算符。

【补充】

是的,我无法定义线程安全的含义。我只想给 item1-item3 一个 NAME。我的另一个疑问来自以下 使用 Interlocked.CompareExchange 实现的类似字段的事件

什么叫线程安全? 到目前为止我们得到的代码是 “线程安全”,因为其他线程做什么并不重要——你 不会从上面的代码中得到 NullReferenceException。然而,如果 其他线程正在订阅或取消订阅该事件, 由于正常原因,您可能看不到最近的更改 内存模型很复杂。

从 C# 4 开始,类似字段的事件是使用 Interlocked.CompareExchange,所以我们可以使用对应的 Interlocked.CompareExchange 调用以确保我们获得最新的 价值。诚然,能够做到这一点并不是什么新鲜事, 但这确实意味着我们可以写

CLEAN EVENT HANDLER INVOCATION WITH C# 6

【问题讨论】:

“我定义了线程安全”——这完全无关紧要。该文档有一个线程安全的定义。你如何重新定义它 - 与现实无关。 “一个联锁的 API 操作实际上应用于 PropertyChanged”——不需要这样的事情。在单个执行线程中,重新排序操作以使您在分配变量之前尝试访问它是无效的。 【参考方案1】:

您需要了解关于线程安全的一件事。好吧,有几个:

仅在记录时提供。默认是 NO api 是线程安全的。 它的成本很高。任何锁定都是有代价的——所以如果没有必要,应该避免。 最后,特别是当你谈到 UI 元素时,框架中有非常具体的线程规则 - 一直到 windows 中的规则。 STA - 单线程单元,只有一个线程。仅限 UI 线程。

所以,不,没有什么神奇的机制可以保证某些文件不保证每个文件,因为这意味着每次都必须支付费用,主要是在不需要的时候。

.NET 中的事件机制是单线程的。时期。忍受它。它们回到 UI 中的通知机制,并且在那里,对于可能比您更早的规则(即它们回到 ActiveX UI 元素的时代,偶然仍然存在于即标准文件对话框中)这是“任何东西”的域UI 中的内容只能由一个 ui 线程更改”。

【讨论】:

以上是关于更多 C# 事件和线程安全的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的线程安全异步代码

创建事件调度线程安全信号量

C#:高效的线程安全队列ConcurrentQueue<T>

C# 线程安全与 lock锁

C#复习总结探究各类数据结构(ArrayListQueueStack)及线程安全问题和yeild关键字

在 C# 中使用 Interlocked 获取和设置线程安全吗?