Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Event handler as parameter

Tags:

c#

events

Okay I don't really know what's wrong with my code and What's going on so

class Activity has the following methods

protected struct EventParams
    {
        public object sender;
        public EventArgs e;
    }
private EventParams WaitEventRaise_Body(ref EventHandler<EventArgs> handler, int timeout)
    {
        AutoResetEvent receiver = new AutoResetEvent(false);
        EventParams result = new EventParams();

        EventHandler<EventArgs> handle = new EventHandler<EventArgs>((sender, e) =>
        {
            result.e = e;
            result.sender = sender;
            receiver.Set();
        });

        handler += handle;

        if (timeout > 0)
        {
            receiver.WaitOne(timeout);
        }
        else
        {
            receiver.WaitOne();
        }

        return result;
    }

protected EventParams WaitEventRaise(ref EventHandler<EventArgs> handler)
{
    return WaitEventRaise_Body(ref handler, -1);
}
protected EventParams WaitEventRaise(ref EventHandler<EventArgs> handler, int timeout)
{
    return WaitEventRaise_Body(ref handler, timeout);
}

Okay so I find myself writing over and over again the AutoResetEvent thing so I decided to create a method. But when I try to call this method from derived class Bot : Activity

EventParams eventResult = WaitEventRaise(ref currentJob.JobReported);

gives

Error 30 The best overloaded method match for Project.Activity.WaitEventRaise(ref System.EventHandler)' has some invalid arguments

currentJob is a Job : Activity class that has the event

public event EventHandler<JobReport> JobReported;

and

class JobReport : EventArgs

What I want to do is there is a bot thing does jobs, actually it creates jobs and waits them for finish their work. Job class raises event inside to make bot class noticed that it finished its work. And bot class waits until job raises event. So I hope its clear. And I'm sorry that english is not my native language.

like image 966
user1046403 Avatar asked Jul 30 '13 13:07

user1046403


1 Answers

Basically, you can't refer to an event like that. Two options:

  • Pass in delegates for "adding a handler" and "removing a handler":

    EventParams eventResult = 
        WaitEventRaise<JobReport>(handler => currentJob.JobReported += handler,
                                  handler => currentJob.JobReported -= handler);
    

    where WaitEventRaise would be declared as:

    EventParams WaitEventRaise<T>(Action<EventHandler<T>> add,
                                  Action<EventHandler<T>> remove)
                                 where T : EventArgs
    
  • Pass in the EventInfo corresponding to the event, which you'd fetch with reflection

Neither of these is terribly pleasant - it's a problem that Rx comes up against as well.

like image 200
Jon Skeet Avatar answered Sep 19 '22 00:09

Jon Skeet