views:

29

answers:

1

How to pass parameters to the function called by ElapsedEventHandler?

My code:

private static void InitTimer(int Index)
{
    keepAlive[Index] = new Timer();
    keepAlive[Index].Interval = 3000;
    keepAlive[Index].Elapsed += new ElapsedEventHandler(keepAlive_Elapsed[, Index]);
    keepAlive[Index].Start();
}

public static void keepAlive_Elapsed(object sender, EventArgs e[, int Index])
{

    PacketWriter writer = new PacketWriter();
    writer.AppendString("KEEPALIVE|.\\");
    ServerSocket.Send(writer.getWorkspace(), Index);
    ServerSocket.DisconnectSocket(Index);
}

What I want to do is between the brackets ([ and ]). But just doing it like that obviously doesn't work...

+3  A: 

You can't do this within the method itself - you have to make your event handler aware of its context, effectively. The simplest way of doing this is with a lambda expression or anonymous method:

private static void InitTimer(int Index)
{
    keepAlive[Index] = new Timer();
    keepAlive[Index].Interval = 3000;
    keepAlive[Index].Elapsed += delegate { KeepAliveElapsed(Index); };
    keepAlive[Index].Start();
}

public static void KeepAliveElapsed(int Index)
{    
    PacketWriter writer = new PacketWriter();
    writer.AppendString("KEEPALIVE|.\\");
    ServerSocket.Send(writer.getWorkspace(), Index);
    ServerSocket.DisconnectSocket(Index);
}

Here, the anonymous method (the bit with the delegate keyword) has created a delegate which knows about the Index parameter to InitTimer. It just calls the KeepAliveElapsed method. I've used the anonymous method syntax because you didn't need the sender or event args; if you did need them I'd probably use a lambda expression instead, e.g.

private static void InitTimer(int Index)
{
    keepAlive[Index] = new Timer();
    keepAlive[Index].Interval = 3000;
    keepAlive[Index].Elapsed += (sender, args) => KeepAliveElapsed(sender, Index);
    keepAlive[Index].Start();
}

public static void KeepAliveElapsed(object sender, int Index)
{    
    PacketWriter writer = new PacketWriter();
    writer.AppendString("KEEPALIVE|.\\" + sender);
    ServerSocket.Send(writer.getWorkspace(), Index);
    ServerSocket.DisconnectSocket(Index);
}

(Note that conventionally the Index parameter should be called index, btw.)

Jon Skeet
I have trouble understanding this. Doesn't the Elapsed event expect a ElapsedEventHandler delegate?
SWeko
Thank you, accepted! But why should it be called index?
lesderid
@lesderid: Parameter names are conventionally in camelCase rather than PascalCase.
Jon Skeet
@SWeko: Yes, and we're creating an ElapsedEventHandler, either with an anonymous method or with a lambda expression. That delegate happens to call `KeepAliveElapsed` but that doesn't have to have the same signature at all.
Jon Skeet
Missed that. So we are basically doing `timer.Elapsed +=new ElapsedEventHandler((sender, args) => KeepAliveElapsed(index); );`
SWeko
@SWeko: Yes, although it would be pretty odd to have the "new EventHandler" part when using a lambda expression.
Jon Skeet