如何将多个参数传递给C#线程?

时间:2010-03-22 05:48:34

标签: c# multithreading

如何将多个参数传递给C#线程?任何例子都将不胜感激。

6 个答案:

答案 0 :(得分:43)

假设你有一个方法:

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()

答案 1 :(得分:4)

解决方案 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和聚合所有参数的自定义类(如果有更多)。使用parameterizedThreadStart,您可以在执行时传递参数。这看起来像这样:

    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).

(执行的顺序不是确定性的,它是线程之间的竞争)

答案 2 :(得分:4)

对于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)
{

}

答案 3 :(得分:0)

将参数传递给线程的最简单方法之一

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)
        {

        }

答案 4 :(得分:0)

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)
        {

        }

答案 5 :(得分:0)

您可以使用数组设置多个值的参数....

 class Program
{
    public static void Method1(object param)
    {
        object[] parameters = (object[])param;
        int param1 = (int)parameters[0];
        string param2 = (string)parameters[1];
        Console.WriteLine("Int : {0}  \nString : {1}", param1, param2);

    }

    static void Main(string[] args)
    {
        Thread thread = new Thread(new ParameterizedThreadStart(Method1));
        thread.Start(new object[] { 10, "String value" });
        Console.Read();
    }
}