0

I have an class with an event, then in another .cs file i have another class where I subscribe to the event. But the event is never successfully triggered, and for some reason the event is null. What am I doing wrong?

First class:

class TestClass
{
    public static void CountStart()
    {

        int CountVal = 0;
        do
        {
            CountVal = CountVal + 1;
            if (CountVal % 5 == 0)
            {
                SimpleEventSender EventSender = new SimpleEventSender();
                EventSender.StartEvent();
            }
            Thread.Sleep(1000);
        } while (CountVal < 100);
    }
}

The event class:

public class SimpleEventSender
{
    public event EventHandler NewEvent;
    public void StartEvent()
    {
        if (NewEvent != null)
        {
            NewEvent(this,null);
        }

    }
}

And the class where I subscribe to the event:

public partial class Form1 : Form
{
    public Form1()
    {
        SimpleEventSender newevent1 = new SimpleEventSender();
        newevent1.NewEvent += new_event;
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        TestClass class1 = new TestClass();
        TestClass.CountStart();


    }

    public void new_event(object sender, EventArgs e)
    {
        MessageBox.Show("multiple of 5 reached");
    }
}

I have tried following the answers at "Notify when event from another class is triggered" but it didnt seem to work.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • You subscribe an event handler to the event of one SimpleEventSender object. But you raise the event of another SimpleEventSender object to which you have not subscribed an event handler. Do you see/understand it? You have to subscribe to the event of _that_ SimpleEventSender object on which you raise the event. –  Sep 26 '18 at 16:57
  • Also, using C# 6 and above, you can simplify the `EventHandler` call in `StartEvent` to `NewEvent?.Invoke(this, new EventArgs() /*or null*/);` – Ivan García Topete Sep 26 '18 at 17:02

2 Answers2

4

The event handlers are associated with an instance of the class (SimpleEventSender in this case).

You're creating multiple SimpleEventSender instances:

  • One in the Form1 constructor, where you subscribe to the event
  • One every 5 iterations of CountStart, where you raise the event - but on a new instance of SimpleEventSender, that doesn't have any subscribers

You almost certainly want to use a single instance of SimpleEventSender, e.g.

// The form now retains a reference to the instance of SimpleEventSender
public partial class Form1 : Form
{
    private readonly SimpleEventSender eventSender;

    public Form1()
    {
        eventSender = new SimpleEventSender();
        eventSender.NewEvent += new_event;
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        TestClass class1 = new TestClass();
        TestClass.CountStart(eventSender);
    }

    public void new_event(object sender, EventArgs e)
    {
        MessageBox.Show("multiple of 5 reached");
    }
}

// TestClass now *accepts* an EventSender rather than creating its own instances
class TestClass
{
    public static void CountStart(SimpleEventSender eventSender)
    {
        // Variable name modified to be more conventional
        // A "for" loop would be more idiomatic too
        int count = 0;
        do
        {
            count++;
            if (count % 5 == 0)
            {
                eventSender.StartEvent();
            }
            Thread.Sleep(1000);
        } while (count < 100);
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

That's because you're assigning this function to the different event of instance of SimpleEventSender.

public Form1()
    {
        SimpleEventSender newevent1 = new SimpleEventSender();

        // You are subscribing to the event of this instance            
        newevent1.NewEvent += new_event;
        InitializeComponent();
    }

-

    public static void CountStart()
    {

        int CountVal = 0;
        do
        {
            CountVal = CountVal + 1;
            if (CountVal % 5 == 0)
            {

                // But here you are creating another instance of SimpleEventSender so it doesn't have anything subscribed to it
                SimpleEventSender EventSender = new SimpleEventSender();
                EventSender.StartEvent();
            }
            Thread.Sleep(1000);
        } while (CountVal < 100);
    }

In other words - you are subscribing to one object in the Form1() constructor and you are calling "StartEvent()" function from totally different object in CountStart() function.

QmlnR2F5
  • 934
  • 10
  • 17