如何在C#中向线程传递参数?

如何在C#中向线程传递参数?,c#,multithreading,C#,Multithreading,考虑以下代码: namespace MyThreads { public class HisThread { public int Thread2(int start, int end, int[] arr) { int sum = 0; // foreach (int i in arr) for (int i = start; i <= end; i++)

考虑以下代码:

namespace MyThreads
{
    public class HisThread
    {
        public int Thread2(int start, int end, int[] arr)
        {
            int sum = 0;
            // foreach (int i in arr)
            for (int i = start; i <= end; i++)
            {
                sum += arr[i];
            }
            return sum;
        }

    }


    public class MyThread
    {
        public void Thread1()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Hello world " + i);
                Thread.Sleep(1);
            }
        }
    }


    public class Test
    {

        public static void Main()
        {
            int[] arr = new int[30];
            for (int i = 0; i < 30; i++ )
            {
                arr[i] = i;
            }

            Console.WriteLine("Before start thread");

            // thread 1 - without params
            MyThread thr = new MyThread();
            Thread tid1 = new Thread(new ThreadStart(thr.Thread1)); // this one is OK
            tid1.Start();

            // thread 2 - with params
            HisThread thr2 = new HisThread();
            Thread tid2 = new Thread(new ParameterizedThreadStart(thr2.Thread2));
        }
    }

}
知道怎么解决吗

谢谢

委托要求方法接受
对象的单个参数
类型:

public delegate void ParameterizedThreadStart(object obj)
也就是说,你的方法应该是

public class HisThread
{
    public void Thread2(object obj)
    {
        // ...
    }
}
还有一种方法接受参数:

 // thread 2 - with params
 HisThread thr2 = new HisThread();
 Thread tid2 = new Thread(new ParameterizedThreadStart(thr2.Thread2));
 tid2.Start(parameter);
如果您使用的是.NET 4.5,则可以改用:

Task.Run(()=>thr2.Thread2(开始、结束、数组))
这可能有助于:

class MyParameter
{
    public int Start, End; //Use Properties for these
    public int[] Array;    //Use Properties for this
}
然后:


该代码的问题在于
ParameterizedThreadStart
是一种委托类型,这意味着它与特定的方法签名相关联——特别是,该签名是
无效方法(对象)
。您的方法
Thread2
与该签名不匹配,因此出现编译器错误

那么如何解决呢?这要看情况了

ParameterizedThreadStart
具有该特征,因为它是有史以来最通用的方法。其背后的思想是,您可以传递某个自定义类型的对象,该对象包含函数所需的所有状态,如下所示:

class Params
{
    public int Start { get; set; }
    public int End { get; set; }
    public int[] Array { get; set; }
}

var p = new Params { 0, 0, new int[0] };
var t = new Thread(thr2.Thread2);
t.Start(p);

public int Thread2(object param)
{
    var p = (Params)param;
    // and now get your arguments as p.Start etc.
}
虽然这是可行的,但它非常笨拙,迫使您放弃
Thread2
的最自然的签名。但是,通过插入匿名函数来解包参数,您可以做得更好:

int start = 0, end = 0;
var arr = new int[0];
var t = new Thread(() => thr2.Thread2(start, end, arr));
如果您选择这样做,您必须注意这样一个事实:由于编译器用于将参数传递给thread方法的机制,在定义
t
之后但在开始之前更改其值将使
Thread2
看到更改的值

为什么它不能编译

因为您的代理与所需签名不匹配

知道怎么解决吗

解决方案1: 创建自己的类型并传递数据

public class MyClass
{
    public int start {get;set;};
    public int end {get;set;};
    public int[] arr {get;set;};
}

public void Thread2(object parameter)
{
    MyClass obj = (MyClass)parameter;
    //Make use of obj
}

HisThread thr2 = new HisThread();
Thread tid2 = new Thread(new ParameterizedThreadStart(thr2.Thread2));
tid2.Start(new MyClass{...});
解决方案2: 就用一个兰姆达

HisThread thr2 = new HisThread();
Thread tid2 = new Thread(() => thr2.Thread2(param1,param2,param3));
tid2.Start();
但是,如果调用此函数后立即调整变量,则可能会产生一些副作用,因为实际上是通过引用传递变量。

尝试以下方法:

Thread thread = new Thread(() => new HisThread().Thread2(0, 3, new int[] { 1, 2, 3, 4 }));
如果您在2.0中:

Thread thread = new Thread(delegate() { new HisThread().Thread2(0, 3, new int[] { 1, 2, 3, 4 }); });

最简单的方法是像这样委派

    ThreadStart ts = delegate
    {
          bool moreWork = DoWork("param1", "param2", "param3");
          if (moreWork) 
          {
              DoMoreWork("param1", "param2");
          }
    };
    new Thread(ts).Start();

ParameterizedThreadStart仅适用于类型为“object”的参数。您必须将Thread2的方法签名更改为仅使用“object”类型的参数,如果您使用线程搜索传递参数,您将得到太多的答案。这将非常有用:@SriramSakthivel just copy paste问题,已经修复,谢谢,这种情况经常发生:)
Thread thr2 = new Thread(() => thr2.Thread2(0, 1, arr));
Thread thread = new Thread(() => new HisThread().Thread2(0, 3, new int[] { 1, 2, 3, 4 }));
Thread thread = new Thread(delegate() { new HisThread().Thread2(0, 3, new int[] { 1, 2, 3, 4 }); });
    ThreadStart ts = delegate
    {
          bool moreWork = DoWork("param1", "param2", "param3");
          if (moreWork) 
          {
              DoMoreWork("param1", "param2");
          }
    };
    new Thread(ts).Start();