2013-02-25 1 views
0

Используя много задач, иногда мне нужно передать 2 или более переменных в новый поток через лямбда. Я не уверен, что я использую лямбда, эти переменные всегда передаются в другую задачу/поток как часть ExecutionContext Thread.Можно ли передать две или более переменных в новую задачу (Thread) через Lambda?

Task<int> t = Task.Run(() => MyFunction(Var1, Var2, Var3), cts.Token); 
+0

пример кода –

+0

Он должен быть безопасным, за исключением того, что вам нужно следить за проблемами «закрытия». Образец кода необходим, как говорит Горан. :) –

+0

@GoranObradovic добавленный образец кода. – user960567

ответ

2

Вы не объяснили, что именно вы подразумеваете под безопасностью, поэтому вопрос довольно неоднозначный.

В общем, передача таких аргументов безопасна (хотя это не имеет никакого отношения к ExcutionContext). Но есть несколько вещей, о которых вы должны быть осторожны:

Во-первых, как и при многопоточности, вы должны быть осторожны при обращении к одному и тому же объекту из нескольких потоков одновременно, и для этого вам, скорее всего, потребуется блокировка.

Во-вторых, применяются обычные правила лямбда: переменные, используемые в лямбда, образуют замыкание. Это означает, что любые изменения этих переменных отражаются и в лямбда.

+0

AFAIK, переменные передаются другим потокам в составе ExcutionContext. Например, Thread.Principal, идентификатор Windows, Stack сжатый. Как вы можете сказать, что «это не имеет никакого отношения к ExcutionContext» – user960567

+1

@ user960567 Да, но это часть * контекста, в котором выполняется ваш код *. Но закрытых переменных из лямбда нет, поэтому они не проходят через «ExecutionContext». – svick

1

лично я не очень большой опыта работы с задачами, но от того, что я сделал с ними, это не должно быть теми проблемами, потому что при вызове функции и передать аргументы, которые будут создавать ссылки на этот аргумент переменные поэтому они не будут собирать мусор. Просто следите за тем, чтобы не использовать некоторые переменные из внешнего внешнего пространства (check this answer).

Число аргументов не так важно. Более важно то, как вы используете их в отдельном потоке, и передавать их, как аргументы метода, в порядке. Если вы не знаете КАК передать больше аргументов, см. this answer.

Сценарий проблемы закрытия Мэтью Уотсон упомянул бы выглядеть примерно так:

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

Отказ от ответственности: Этот ответ может быть неправильным, этот код может работать, но я думаю, что ваш код не будет проблем :)

Смежные вопросы