简体   繁体   中英

Piggybacking data on EventArgs or sender for an EventHandler

I am writing a custom scheduler and as such I want to fire off whatever tasks are registered to be run at the current time, without taking so much time that the scheduler misses the next time slot. I have therefore created a thread that sleeps until the next scheduled event and then it wakes and runs that next event or events and then it sleeps again. Tasks are run as processes in the background so I can just set them up and fire them off as quickly as possible. In order to facilitate logging for the controlling process I keep an internal queue of tasks that upon waking, I consume as I fire off the processes, but I also want to have an EventHandler that can then finish the logging for that task by registering how long it took and whether it failed or succeeded once it exits.

Because I am using the Process.Process() class to execute the task in the background, there is no way (I can see) to pass my unique task reference through to the handler so I can finish the logging correctly. I am setting up my handler like the code below.

pTask = new Process();
pTask.Exited += new EventHandler(pTask_Exited);

I deliberately used the term piggyback in my title because in my research I came across a similar question which attracted one answer that said if you need to piggyback data on EventArgs, your design is flawed. I can accept my design may be flawed, but have not been able to find enlightenment as to how I should design it differently and more effectively. Any guidance is appreciated.

You can achieve this using lambdas as follows:

First define a method that will be run when the process exits. This will be instead of any event handler you are currently using, and performs the necessary logging etc.:

void ExitHandler(Process process, YourTaskInfo taskInfo) // YourTaskInfo is some class that contains data about the task that needs to be passed to the handler
{
    Console.WriteLine("Process for task: {0} exited with code: {1}", taskInfo, process.ExitCode);
}

You can then attach this method to the Exited event handler as follows:

pTask.Exited += (s,e) => ExitHandler(pTask, taskInfo);

In this way, you can pass in your unique task reference ( taskInfo ) to the Exited handler, without worrying about any "piggybacking" etc. on the sender or EventArgs.

Get the data from the Process itself, which is passed as the sender :

void pTask_Exited(object sender, EventArgs e)
{
    Process p = (Process)sender;
    TimeSpan duration = p.ExitTime - p.StartTime;
    bool success = p.ExitCode == 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM