gpt4 book ai didi

c# - 是 C# 6 吗? (Elvis op)线程安全吗?如果是这样,如何?

转载 作者:IT王子 更新时间:2023-10-29 04:17:56 28 4
gpt4 key购买 nike

提前致歉:这个问题来自一位试图学习高级 C# 的顽固的、未经改革的 C++ 开发人员。请考虑以下事项:

if (myUserDefinedObject != null)
{
myUserDefinedObject.ToString();
}

这显然不是线程安全的。另一方面,我看过两个教程说 ?。 (空条件运算符或“猫王运算符”)例如,

myUserDefinedObject?.ToString();

线程安全的。除非编译器将 [mutex?] 锁包裹起来(颤抖),否则我不明白这怎么可能是真的。如果这个习语是线程安全的,有人可以指出我如何实现的技术描述吗?如果它不是线程安全的,有没有人有实际说明它不是线程安全的引用资料?

最佳答案

我想澄清 BJ Myers 的(正确)答案。

在 C# 中,可以将事件视为委托(delegate)类型的字段——就像可以将属性视为属性类型的字段一样——并且该“字段”的值可以为空。如果您遇到一个不幸的情况,在一个线程上修改了事件处理程序,而另一个线程正在尝试调用它,您可能会遇到以下情况:

if (this.SomeEvent != null) 
this.SomeEvent( ... );

不是线程安全的。该值可能会发生变化,以便在检查前为非空,在检查后为空,然后程序崩溃。

使此“线程安全”的常用方法(我建议使用该术语)是将值复制到本地,然后测试本地是否为空。这样做的好处是不会因 null 取消引用而崩溃。然而,聪明的开发者会注意到仍然存在竞争!顺序可以是

  • 缓存在线程 A 上的非空事件处理程序
  • 线程 B 上的事件处理程序设置为 null
  • 事件处理程序所需的状态在线程 B 上被销毁
  • 事件处理程序在线程 A 上运行并可怕地死掉

所以从这个意义上说,这种模式不是“线程安全的”。如果您处于这种不幸的境地,您有责任确保实现适当的线程逻辑,以免发生这种情况。你可以随心所欲地这样做。如果您想要能够在一个线程上调用事件处理程序同时在另一个线程上改变事件的(可疑的)好处,那么您必须付出代价以使其安全或处理竞争条件错误。

我个人会像避免瘟疫一样避免这种情况,但我不够聪明,无法编写正确的多线程代码。

现在,至于实际问题:

some_expression ?. ToString();

相同
temp = some_expression
temp == null ? null : temp.ToString()

您认为后一种代码是“线程安全的”吗?

关于c# - 是 C# 6 吗? (Elvis op)线程安全吗?如果是这样,如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35784874/

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