使用带有单例c#的事件处理程序。 EventHandler为null

时间:2015-11-19 14:28:28

标签: c# delegates singleton

我有一个单例类和一个eventHandler sendResponse。 我希望在发布者提出时在订阅者类中执行某些操作 事件。

public class Publisher
{
    private static Publisher instance;
    public event EventHandler SendResponse;

    public static Publisher Instance
    {
        get
        {
            if (instance == null)
                instance = new Publisher();
            return instance;
        }
    }

    public void Send()
    {
        this.SendResponse(instance, EventArgs.Empty);
    }
}

在订阅者中,我说

public string performSomething()
{
       Publisher copy = Publisher.Instance;
       copy.SendResponse += new EventHandler(copy_SendResponse);
       bool isCompleted = false;

       // Start an async task method which is in another class and is the publisher.

       while(isCompleted != true);
       return "Success";
}

//Define the function copy_SendResponse.
public void copy_SendResponse()
{
      isCompleted = true;
}

首先执行订阅者的代码。 但是当我在发布者中调用Send()方法时,SendResponse没有绑定任何东西。 在我正在使用的出版商

 // when async task completes
 Publisher copy = Publisher.Instance;
 copy.Send();
 // end of function

在调试时,当我说copy.Send()时,SendResponse实际上是null。 它会抛出错误“对象引用未设置为对象的实例。”

1 个答案:

答案 0 :(得分:1)

起初,我会将delcare单身人士总是这样:private static Publisher instance = new Publisher();,在我看来,这比吸气者更清楚。其次,始终证明您的活动是否已下载:

private void Send()
{
    if (this.SendResponse != null)
    {
        this.SendResponse(this, EventArgs.Empty); // <<-- pass this
    }
}

如果你想确定,没有其他人可以创建单例类的实例,那么使它成为构造函数private。而是通过this而不是instance,以确保将正确的对象作为发件人传递。

如果您遵循所有规则,您的代码应该有效。我发现您的信息/代码数量没有任何其他问题。

修改

工作示例:

public class Publisher
{
    // Instance
    private static readonly Publisher instance = new Publisher();
    public event EventHandler SendResponse;

    public static Publisher Instance
    {
        get
        {
            return instance;
        }
    }

    /// <summary>
    /// Private constructor
    /// </summary>
    private Publisher()
    {

    }

    public void Send()
    {
        // proof if subscipted
        if (this.SendResponse != null)
        {
            // Pass this
            this.SendResponse(this, EventArgs.Empty);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        var copy = Publisher.Instance;
        copy.SendResponse += Copy_SendResponse;

        var copy2 = Publisher.Instance;
        copy2.Send();

        Console.ReadLine();
    }

    /// <summary>
    /// Event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private static void Copy_SendResponse(object sender, EventArgs e)
    {
        Console.WriteLine("It works!");
    }
}