相关疑难解决方法(0)

事件处理程序不是线程安全吗?

所以我已经阅读过,而不是直接调用事件

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 c# events multithreading thread-safety

29
推荐指数
3
解决办法
1万
查看次数

是否可以从另一个线程观察部分构造的对象?

我经常听说在.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)

.net c# multithreading memory-model thread-safety

27
推荐指数
1
解决办法
1125
查看次数

内存屏障和缓存刷新

是否存在即使使用缓存刷新也会实现内存屏障的arch?我读到内存屏障仅影响CPU重新排序,但我读取了与内存屏障相关的语句:确保所有cpu都会看到值...,但对我来说这意味着缓存刷新/失效.

c caching memory-barriers

9
推荐指数
2
解决办法
4387
查看次数

通过呼叫代表来提高事件 - 为什么不通过事件名称?

我查看了一段旧代码,但无法理解以下内容:

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/

c# events

6
推荐指数
1
解决办法
60
查看次数