views:

583

answers:

2

What is the difference between the two piecees of code below. will there be any issues using the second one.

Scenario 1

private void Log(Exception e)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(Log), e);
}

private void Log(object obj)
{
    Exception e = (Exception)obj;
    Logger.Log(e);
}

Scenario 2

private void Log(Exception e)
{
    ThreadPool.QueueUserWorkItem(
        (obj) => 
            {
                Logger.Log(e);
            });
}

In scenario 2, I am not passing the exception in as a paramter to the ThreadPool. How does the thread marshalling of the exception object occur? Will there be any problems? What are the limitations of doing this if any? The big advantage is that you can pass in any number of parameters very easily.

+11  A: 

The only difference is that in scenario two you are closing over the e variable which effectively moves the stack variable e into a custom type that is moved to the heap so you don't lose it.

I think this ought to work fine.

Edit: As for performance, no there ought not to be a significant difference between the two scenarios. In scenario 1 you are already passing the exception as state to the QueueUserWorkItem method which internally moves that exception reference onto the heap. The only overhead is that when you use a closure is that the compiler creates a type for you and stores any captured variables as fields on that type.

Andrew Hare
Are there any performance implications?
Good answer. Indeed, the lambda expression generates a closure (http://en.wikipedia.org/wiki/Closure_(computer_science)) so that the variable (can be more than one in the general case) can be referenced elsewhere.
Noldorin
@anon: No, there shouldn't be any performance implications as far as I know.
Noldorin
+1  A: 

Just to note, instead of the Lambda, you could do the same with an anonymous method, and it would also work in C# 2.0:

ThreadPool.QueueUserWorkItem(delegate(Object e) 
    { 
        Logger.Log(e as Exception); 
    });
SnOrfus
+1 What you have posted is exactly what the compiler generates for the lambda statement in the OP's question.
Andrew Hare
Yes, but if the OP had included more parameters, then would the anonymous method have worked?
John Saunders