I know that .NET lambda expressions can capture outer variables. However, I have seen it a lot of times that variables are passed explicitly to the lambda expression as a parameter, and the .NET library also seems to support that (e.g. ThreadPool.QueueUserWorkItem).

My question is that what are the limitations of these captures? How about lambdas that are actually executed on a different thread than the one they were created on (e.g. ThreadPool.QueueUserWorkItem, or Thread), or lambas that act as callbacks (i.e. invoked at a later time)?

Generally, when should I rely on captured variables, and when to use explicit parameters? For example:

public void DoStuff()
{
     string message = GetMessage();

     ThreadPool.QueueUserWorkItem(s => SendMessage(message)); // use captured variable
     // -- OR --
     ThreadPool.QueueUserWorkItem(s =>
          {
               string msg = (string)s;
               SendMessage(msg);
          }, message); // use explicit parameter
}

Thank you!

Update: fixed the second ThreadPool.QueueUserWorkItem example.

Edit
Report