Как передать более одного параметра в поток С#? Любой пример будет оценен.
Как передать более одного параметра в поток С#?
Ответ 1
Предположим, что у вас есть метод:
void A(string a, int b) {}
Это должно работать (.NET 2.0):
ThreadStart starter = delegate { A("word", 10); };
Thread thread = new Thread(starter);
thread.Start();
И следующий (более короткий) для более высоких версий:
ThreadStart starter = () => A("word", 10);
Thread thread = new Thread(starter);
//or just...
//Thread thread = new Thread(() => A("word",10));
thread.start()
Ответ 2
Предоставленные tsocks-решения могут быть неприемлемыми для всех ситуаций, поскольку они задают параметры во время создания делегата ThreadStart, а не во время выполнения. Это может привести к ошибкам, поскольку параметры могут измениться до выполнения, что, вероятно, не так, как вы хотите. Предположим, вам нужно создать несколько потоков в цикле, каждый со своими собственными параметрами:
void CreateAndRunThreads()
{
List<ThreadStart> threadStartsList = new List<ThreadStart>();
//delegate creation
for (int i = 0; i < 5; i++)
{
ThreadStart ts = delegate() { PrintInteger(i); };
threadStartsList.Add(ts);
}
//delegate execution (at this moment i=5 in the previous loop)
foreach(ThreadStart ts in threadStartsList)
{
Thread t = new Thread(ts);
t.Start();
}
}
private void PrintInteger(int i)
{
Debug.WriteLine("The integer value: "+i);
}
Результат здесь выглядит следующим образом:
The integer value: 5
The thread 0x17f0 has exited with code 0 (0x0).
The integer value: 5
The integer value: 5
The thread 0x10f4 has exited with code 0 (0x0).
The integer value: 5
The thread 0x1488 has exited with code 0 (0x0).
The integer value: 5
The thread 0x684 has exited with code 0 (0x0).
Обратите внимание, что все делегаты напечатали значение 5, а не 0-4. Это связано с тем, что делегаты ThreadStart используют переменную "i", как это происходит в момент выполнения, а не в момент создания делегата. Поэтому любое изменение (i ++ в цикле) к параметру после момента создания делегата будет отражено в значении параметра при выполнении делегата.
Решение этой проблемы заключается в использовании ParameterizedThreadStart и пользовательского класса, который агрегирует все ваши параметры (если их больше). С параметризованнымThreadStart вы передаете параметры во время выполнения. Это будет выглядеть примерно так:
class CustomParameters
{
public int IntValue { get; set; }
public string FriendlyMessage { get; set; }
}
private void CreateAndRunThreadsWithParams()
{
List<ParameterizedThreadStart> threadStartsList = new List<ParameterizedThreadStart>();
//delegate creation
for (int i = 0; i < 5; i++)
{
ParameterizedThreadStart ts = delegate(object o) { PrintCustomParams((CustomParameters)o); };
threadStartsList.Add(ts);
}
//delegate execution
for (int i=0;i<threadStartsList.Count;i++)
{
Thread t = new Thread(threadStartsList[i]);
t.Start(new CustomParameters() { IntValue = i, FriendlyMessage = "Hello friend! Your integer value is:{0}"});
}
}
private void PrintCustomParams(CustomParameters customParameters)
{
Debug.WriteLine(string.Format(customParameters.FriendlyMessage, customParameters.IntValue));
}
Результат показан здесь:
Hello friend! Your integer value is:1
The thread 0x1510 has exited with code 0 (0x0).
Hello friend! Your integer value is:0
The thread 0x13f4 has exited with code 0 (0x0).
Hello friend! Your integer value is:2
The thread 0x157c has exited with code 0 (0x0).
Hello friend! Your integer value is:3
The thread 0x14e4 has exited with code 0 (0x0).
Hello friend! Your integer value is:4
The thread 0x1738 has exited with code 0 (0x0).
(Порядок выполнения не является детерминированным, это гонка между потоками)
Ответ 3
Для С# 3.0 вы можете избежать уродливого массива объектов, проходящего с помощью анонимных методов:
void Run()
{
string param1 = "hello";
int param2 = 42;
Thread thread = new Thread(delegate()
{
MyMethod(param1,param2);
});
thread.Start();
}
void MyMethod(string p,int i)
{
}
Ответ 4
Отправить несколько параметров в поток на С#. У нас есть аналогичный вопрос поток С# с несколькими параметрами
Ответ 5
один из самых простых способов передать параметр в поток как
Thread xmlThread =new Thread( ()=>WriteLog(LogTypes.Message, "Flag", "Module", "Location", "Text", "Stacktrace"));
xmlThread.Start();
private object WriteLog(LogTypes logTypes, string p, string p_2, string p_3, string p_4, string p_5)
{
}
Ответ 6
public void Start()
{
var t1 = new Thread((message) => { Console.WriteLine(message); });
//the parametirized threadstart accepts objects, it is not generic
var t2 = new Thread(number => { var num = (int)number;
Console.WriteLine(num++);
});
var t3 = new Thread((vals)=> work(vals));
t1.Start();
t2.Start();
t3.Start(20);
}
public void work(params object[] vals)
{
}