所以我已经阅读过,而不是直接调用事件
if (SomeEvent != null)
SomeEvent(this, null);
Run Code Online (Sandbox Code Playgroud)
我应该这样做
SomeEventHandler temp = SomeEvent;
if (temp != null)
temp(this, null);
Run Code Online (Sandbox Code Playgroud)
为什么会这样?第二个版本如何变得线程安全?什么是最佳做法?
我经常听说在.NET 2.0内存模型中,写入始终使用释放围栏.这是真的?这是否意味着即使没有明确的内存屏障或锁定,也不可能在不同于创建它的线程上观察部分构造的对象(仅考虑引用类型)?我显然排除了构造函数泄漏this引用的情况.
例如,假设我们有不可变的引用类型:
public class Person
{
public string Name { get; private set; }
public int Age { get; private set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
Run Code Online (Sandbox Code Playgroud)
是否可以使用以下代码观察除"John 20"和"Jack 21"之外的任何输出,例如"null 20"或"Jack 0"?
// We could make this volatile to freshen the read, but I don't want
// to complicate the core of the question.
private Person person;
private void Thread1()
{
while (true)
{
var personCopy = person; …Run Code Online (Sandbox Code Playgroud) 是否存在即使使用缓存刷新也会实现内存屏障的arch?我读到内存屏障仅影响CPU重新排序,但我读取了与内存屏障相关的语句:确保所有cpu都会看到值...,但对我来说这意味着缓存刷新/失效.
我查看了一段旧代码,但无法理解以下内容:
public event EventHandler NameChanged;
#endregion
#region protected void OnNameChanged(EventArgs args)
/// <summary>
/// Raises NameChanged event.
/// </summary>
/// <param name="args">Event arguments.</param>
protected void OnNameChanged(EventArgs args)
{
EventHandler eh = this.NameChanged;
if (eh != null)
{
eh(this, args);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么通过调用委托来引发事件?难道我不能像往常一样简单地调用事件本身(NameChanged)吗?
编辑:我可以在MSDN上看到这也是建议:https://docs.microsoft.com/en-us/dotnet/standard/events/