views:

50

answers:

2

Hello all,

I have the following code:

public void SetMove(Position3D pos, float time, float linearity, bool relative)
{
    ExecuteOnActiveClients(delegate(NeuroClient client)
                               {
                                   client.Engine.GetProcAnimation(name).SetMove(pos, time, linearity, relative);
                               }, true, true);
}

Where ExecuteOnActiveClients pushes the delegate in a queue, consumed asynchronously, and has the following signature:

void ExecuteOnActiveClients(ClientDelegate action, Boolean parallel, Boolean wait, Boolean lockClient)

I have a lot of functions which look like this one, and which may be called concurrently.

I have noticed that I must store the value of name (which is a private field of the class) in a variable in the function before I execute ExecuteOnActiveClients to have this code work well, because if I don't, the delegate uses the last value of name, and not the value the field had when the function was called.

I guess this is a problem of scope, because the parameters of the function (pos, time, linearity and relative) are correct.

Is there a way to force the delegate to use the value of name when it was created, and not the value of name when it is executed?

I'd like to avoid to store the value in each of the lot of functions which use ExecuteOnActiveClients if it possible.

Thanks in advance

Mike

+2  A: 

Just before creating your delegate, create a temporary local variable containing the value of name, and use that in your delegate.

Joachim VR
+2  A: 

Currently the delegate isn't storing the value of name at all. It's capturing this, and then using it to resolve this.name whenever you refer to it.

This is the way both anonymous methods and lambda expressions work, and there's nothing you can do to change their behaviour: creating a local variable is the workaround. (That will still be capturing that variable rather than its current value, but you can presumably make sure you don't change the local variable's value afterwards.)

For more information, and another trap you can easily fall into, I urge you to read Eric Lippert's blog posts on "Closing over the loop variable considered harmful" (part 1, part 2).

Jon Skeet
That's what I thought... I will then have to do that way. Thanks!
Mike