Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data with events

Tags:

c#

events

I need to pass data with an event. Currently, when receiving more data (via comport), the event will fire but the previous event (&data) is not handled yet, so the data gets overwritten.
How can I handle the event &data in a safe way? I have multiple events like this (15x), so I am not sure if using a queue for the data is the best way or pass data along with the event (like S.O. item 4215845).

Example (this example is with a string, but I also use arrays, bools etc):

At the 'sender' side (class1):

public event EventHandler evDiaStringMessage = delegate { };
private void evDiaStringMessageEvent()
{
    evDiaStringMessage(this, new EventArgs());
}
private static string _DiaString;
public string DiaString
{
    get { return _DiaString; }
    set { _DiaString = value; }
}

DiaString contains the data and gets overwritten when evDiaStringMessage is fired too soon.

At the 'receiver / GUI' side (class2):

dia.evDiaStringMessage += new EventHandler(dia_evDiaStringMessage);

private delegate void dia_evDiaStringMessageCallBack(object sender, EventArgs e);
void dia_evDiaStringMessage(object sender, EventArgs e)
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke(new dia_evDiaStringMessageCallBack(dia_evDiaStringMessage), new object[] { sender, e});
    }
    else
    {
        frmcomm.CommTextBox("Receiver message: " + dia.DiaString + "\r\n", Color.Red);
    }
}

dia.DiaString does not contain the expected data (previous data), but all events are 'received'.

Your help is very much appreciated! Even more with an example!

Edit:

I changed the code to:

At the 'sender' side (class1):

public event EventHandler<DiaStringEventArgs> evDiaStringMessage ;
public class DiaStringEventArgs : EventArgs
{
    public string DiaString  { get; set; }
}

private void evDiaStringMessageEvent(DiaStringEventArgs e)
{
    EventHandler<DiaStringEventArgs> handler = evDiaStringMessage;
    if (handler != null)
        handler(this, e);
}

...

private void PrepareDataAndFireEvent()
{
    DiaStringEventArgs args = new DiaStringEventArgs(); 
    args.DiaString = ByteToString(data);
    evDiaStringMessageEvent(args);
}

At the 'receiver / GUI' side (class2):

dia.evDiaStringMessage += new EventHandler<ifDiA10.DiaStringEventArgs>(dia_evDiaStringMessage);

private delegate void dia_evDiaStringMessageCallBack(object sender, ifDiA10.DiaStringEventArgs e);
void dia_evDiaStringMessage(object sender, ifDiA10.DiaStringEventArgs e)
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke(new dia_evDiaStringMessageCallBack(dia_evDiaStringMessage), new object[] { sender, e});
    }
    else
    {
        frmcomm.CommTextBox("Receiver message: " + e.DiaString + "\r\n", Color.Red);
    }
}
like image 503
Ruudster Avatar asked Nov 19 '12 13:11

Ruudster


People also ask

Can we pass in data when an event is fired?

listener(Function) The function to be called when the event is fired. The listener function is called with the data object passed to fire , extended with target and type properties.

What is CustomEvent?

The CustomEvent interface represents events initialized by an application for any purpose. Note: This feature is available in Web Workers.


2 Answers

You can store your data in a custom EventArgs class:

public class ReceivedDataEventArgs : EventArgs
{
   // Add the properties you require
}

The event is defined like so:

public event EventHandler<ReceivedDataEventArgs> ReceivedData;

Your handler will take in an instance your class instead of the EventArgs object, and hence you'll have the correct data.

like image 129
Jon B Avatar answered Oct 24 '22 00:10

Jon B


You should pass the value of dia.DiaString when the event is raised rather than reading it back when the event is handled.

You can do this by extending the EventArgs class and creating custom properties.

If you need an example let me know.

like image 44
Kami Avatar answered Oct 24 '22 02:10

Kami