Im trying to write to an API and I need to call an eventhandler when I get data from a table. Something like this:
public override bool Run(Company.API api)
{
SomeInfo _someInfo = new SomeInfo();
if (_someInfo.Results == 1)
return true;
else
return false;
using (MyTable table = new MyTable(api))
{
table.WhenData += new EventHandler<DataEventArgs<Record>>(table_WhenData);
table.WhenDead += new EventHandler<EventArgs>(table_WhenDead);
table.Start();
}
public void table_WhenData(object sender, DataEventArgs<Record> e)
{
return true;
}
The problem that Im having is I dont know how to pass a return value back from table_WhenData to the Run method.
Ive tried many ways (like trying to pass _someInfo to the method) but I just cant seem to get the syntax right.
Any suggestion is greatly appreciated.
Firing an event is a one-way signal. By default most event handlers return void , because single event may have several subscribers, and return value could become ambiguous. However, it is possible for handlers to return values. Simple delegates may have any return type.
The EventHandler delegate is a predefined delegate that specifically represents an event handler method for an event that does not generate data. If your event does generate data, you must use the generic EventHandler<TEventArgs> delegate class.
Of course you can. (If it was the event you define yourself, you would need to create you own event arguments class where you would put all the information you need.
Each key node has a handler that receives key events when the key has focus. The handler responds to the key-pressed and key-released events for the Enter key by changing the color of the key on the screen. The event is then consumed so that the keyboard node, which is the parent node, does not receive the event.
The common pattern here is not to return any data from the event handler, but to add properties to your event argument object so that the consumer of the event can set the properties which the caller can then access. This is very common in UI handling code; you see the Cancel event concept all over the place.
The following is pseudo code, and not compile ready. Its intent is to show the pattern.
public class MyEventArgs : EventArgs { public bool Cancel{get;set;} } public bool fireEvent() { MyEventArgs e=new MyEventArgs(); //Don't forget a null check, assume this is an event FireEventHandler(this,e); return e.Cancel; } public HandleFireEvent(object sender, MyEventArgs e) { e.Cancel=true; }
Edit
I like how Jon Skeet worded this: make the EventArgs
mutuable. That is, the consumer of the event can modify the state of the EventArgs
object allowing for the raiser of the event to get to that data.
I know this is an old post, but just in case anyone comes across it, it is certainly possible to do this. You declare your own delegate that returns a value, then base the event off this new delegate. Here is an example:
In the event declarer / publisher:
// the delegate public delegate string ReturnStringEventHandler(object sender, EventArgs args); // the event public event ReturnStringEventHandler StringReturnEvent; // raise the event protected void OnStringReturnEvent(EventArgs e) { if (StringReturnEvent != null) // make sure at least one subscriber // note the event is returning a string string myString = StringReturnEvent(this, e); }
In the event subscriber:
// Subscribe to event, probably in class constructor / initializer method StringReturnEvent += HandleStringReturnEvent; // Handle event, return data private string HandleStringReturnEvent(object sender, EventArgs e) { return "a string to return"; }
.NET provides an example of this in the AssemblyResolve event, which uses the ResolveEventHandler delegate to return data, in this case a reference to the desired Assembly. MSDN Article on AssemblyResolve event
I have personally used both the AssemblyResolve event and the custom delegate technique to return data from an event, and they both work as expected on Visual Studio 2010.
The only way you can do it is to make one of the arguments (preferably the "args" rather than the sender) mutable. If it's not already mutable, you've basically got problems - there's just no way of getting the information out.
(Okay, there's one way - you can keep the event argument itself immutable, but make one member of it a method which ends up calling a delegate registered by the code raising the event in the first place. But that's horrible...)
A simple solution is to use a closure:
public override bool Run() {
SomeInfo someInfo = ...
table.WhenData += (obj, args) => {
someInfo.Return = something
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With