c# - 以拳击般的方式召集委托(delegate)

标签 c# .net delegates convention invocation

我经常看到委托(delegate)调用的代码示例如下:

`

    public delegate void DelegateThreadActivity<T, U> (T sender, U e);

    public event DelegateThreadActivity<Thread, System.EventArgs> OnStart = null;
    public event DelegateThreadActivity<Thread, System.EventArgs> OnStop = null;

    // Helper method for invocation.
    public void RaiseOnStart ()
    {
        DelegateThreadActivity<Thread, System.EventArgs> instance = null;

        try
        {
            instance = this.OnStart;
            // OR
            instance = (DelegateThreadActivity) (object) this.OnStart;

            if (instance != null)
            {
                instance(this, System.EventArgs.Empty);
            }
        }
        catch
        {
        }
    }

`

为什么要使用 [instance] 对象?起初我以为这是公司惯例,但也见过经验丰富的开发人员这样做。有什么好处?

最佳答案

这样做是为了线程安全,并防止在委托(delegate)变为 null 时引发异常。

考虑这段代码:

if (this.OnStart != null)
{
  this.OnStart(this, System.EventArgs.Empty);
}

在执行 if 和执行 this.OnStart 之间,OnStart 委托(delegate)可能已被操纵(可能更改为 null,这将导致异常)。

在您在问题中提供的表格中,将制作委托(delegate)的副本并在执行时使用。原始委托(delegate)中的任何更改都不会反射(reflect)在副本中,这将防止出现异常。但这有一个缺点:由于在此期间的任何更改都不会反射(reflect)在副本中,副本中还包括任何非 null 状态,将导致调用委托(delegate)已被删除或不调用委托(delegate)最近添加到它。

关于c# - 以拳击般的方式召集委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10467467/

相关文章:

c# - 在没有外部委托(delegate)定义的情况下定义 C# 事件

python - 如何使用 QStyledItemDelegate 只绘制背景,而不覆盖文本?

c# - WPF:剪切并保存图像

c# - Linq to sql 表达式树执行区问题

.net - 为什么 OnXXX 事件引发器方法不返回值?

c# - 'string' 不包含 'TryParse' 的定义

c# - 如何在 c#.net 中返回数据集

c# - Visual Studio 2015 上缺少引用错误

c# - LINQ 多重排序依据

c# - 用 lambda 表达式替换委托(delegate)