0

Using lot of Tasks, sometimes I need to pass 2 or more variables to new thread via lambda. I am not sure if I use lambda, these variables always passed to another task/thread as a part of Thread's ExecutionContext.

Task<int> t = Task.Run(() => MyFunction(Var1, Var2, Var3), cts.Token);
Cœur
  • 37,241
  • 25
  • 195
  • 267
Imran Qadir Baksh - Baloch
  • 32,612
  • 68
  • 179
  • 322

2 Answers2

3

You didn't explain what exactly do you mean by safe, so the question is quite ambiguous.

In general, passing arguments like this is safe (though it has nothing to do with ExecutionContext). But there are several things you have to be careful about:

First, as always with multithreading, you have to be careful about accessing the same object from multiple threads at the same time and you should most likely use locking for that.

Second, the normal rules of lambdas apply: the variables used in the lambda form a closure. That means that any changes to those variables are reflected in the lambda too.

svick
  • 236,525
  • 50
  • 385
  • 514
  • AFAIK, variables are passed to other threads as a part of ExcutionContext. For example, Thread.Principal, Windows identity, Stack compressed. How you can say that `it has nothing to do with ExcutionContext` – Imran Qadir Baksh - Baloch Feb 26 '13 at 05:44
  • 1
    @user960567 Yeah, but these are part of the *context in which your code executes*. But closed over variables from a lambda are not, so they don't go through `ExecutionContext`. – svick Feb 26 '13 at 07:35
1

I personally do not have very much experience with tasks, but from what I did with them, this should not be te problem, because when you call function and pass arguments, that will create references to these argument variables so they will not be garbage collected. Just take care not to use some variables from outer outer scope (check this answer).

Number of arguments is not so important. More important is how you use them inside separate thread, and passing them like method arguments is ok. If you don't know HOW to pass more arguments, see this answer.

The scenario with closure problems Matthew Watson mentioned would look something like this:

void Method(){
    var someVar = GetSomeVar();
    var t = Task.Run(() => { 
        // internal closure uses outer private variable
        DoSomething(someVar);
    });
    someVar = somethingElse;
}

Disclaimer: This answer MAY be wrong, this code MAY work, but I think that your code will not have problems :)

Community
  • 1
  • 1
Goran Obradovic
  • 8,951
  • 9
  • 50
  • 79