Как передать больше чем один параметр потоку C#?

Как передать больше чем один параметр потоку C#? Любой пример будет цениться.

17
задан ЯegDwight 22 March 2010 в 10:12
поделиться

3 ответа

Предположим, у вас есть метод:

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()
43
ответ дан 30 November 2019 в 10:39
поделиться

Для C # 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
ответ дан 30 November 2019 в 10:39
поделиться

Решения, предоставленные 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).

(Порядок выполнения не детерминирован, это гонка между потоками)

4
ответ дан 30 November 2019 в 10:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: