C# ThreadStart参数

C# ThreadStart参数,c#,multithreading,C#,Multithreading,如何使用C#中的参数启动线程?是的: Thread t = new Thread (new ParameterizedThreadStart(myMethod)); t.Start (myParameterObject); 线程构造函数的两个重载之一使用ParameterizedThreadStart委托,该委托允许您向start方法传递单个参数。不幸的是,虽然它只允许一个参数,但这样做是不安全的,因为它将其作为对象传递。我发现使用lambda表达式捕获相关参数并以强类型方式传递它们要容易得多

如何使用C#中的参数启动线程?

是的:

Thread t = new Thread (new ParameterizedThreadStart(myMethod));
t.Start (myParameterObject);

线程构造函数的两个重载之一使用ParameterizedThreadStart委托,该委托允许您向start方法传递单个参数。不幸的是,虽然它只允许一个参数,但这样做是不安全的,因为它将其作为对象传递。我发现使用lambda表达式捕获相关参数并以强类型方式传递它们要容易得多

试试下面的方法

public Thread StartTheThread(SomeType param1, SomeOtherType param2) {
  var t = new Thread(() => RealStart(param1, param2));
  t.Start();
  return t;
}

private static void RealStart(SomeType param1, SomeOtherType param2) {
  ...
}
您可以使用委托:

string parameter = "Hello world!";
Thread t = new Thread(new ParameterizedThreadStart(MyMethod));
t.Start(parameter);

ParameterizedThreadStart
接受一个参数。您可以使用它发送一个参数,或者发送包含多个属性的自定义类

Thread thread = new Thread(Work);
thread.Start(Parameter);

private void Work(object param)
{
    string Parameter = (string)param;
}
另一种方法是将要作为实例成员启动的方法与要设置的参数的属性一起放入类中。创建类的实例,设置属性并启动指定实例和方法的线程,然后方法可以访问属性

Thread thread = new Thread(Work);
thread.Start(Parameter);

private void Work(object param)
{
    string Parameter = (string)param;
}
参数类型必须是对象

编辑:


虽然这个答案并不正确,但我建议不要使用这种方法。使用lambda表达式更易于阅读,并且不需要类型转换。请参见此处:

您可以使用该方法并传入值。

您可以使用lambda表达式

private void MyMethod(string param1,int param2)
{
  //do stuff
}
Thread myNewThread = new Thread(() => MyMethod("param1",5));
myNewThread.Start();

这是迄今为止我能找到的最好的答案,它既快又简单。

我在传递的参数中遇到了问题。 我将整数从for循环传递给函数并显示它,但它总是给出不同的结果。类似于(1,2,2,3)(1,2,3)(1,1,2,3)(1,1,2,3)等,带有参数化线程启动委托

这个简单的代码很有魅力

Thread thread = new Thread(Work);
thread.Start(Parameter);

private void Work(object param) 
{
 string Parameter = (string)param; 
}

像这样使用lambda的简单方法

Thread t = new Thread(() => DoSomething("param1", "param2"));
t.Start();
private void DoSomething(int param1, string param2)
{
    //DO SOMETHING..
    void ts()
    {
        if (param1 > 0) DoSomethingElse(param2, "param3");
    }
    new Thread(ts).Start();
    //DO SOMETHING..
}
您甚至可以使用
ThreadStart
委派,就像这样

ThreadStart ts = delegate
{
     bool moreWork = DoWork("param1", "param2", "param3");
     if (moreWork) 
     {
          DoMoreWork("param4", "param5");
     }
};
new Thread(ts).Start();
使用.NET 4.5+甚至像这样的清洁剂

Thread t = new Thread(() => DoSomething("param1", "param2"));
t.Start();
private void DoSomething(int param1, string param2)
{
    //DO SOMETHING..
    void ts()
    {
        if (param1 > 0) DoSomethingElse(param2, "param3");
    }
    new Thread(ts).Start();
    //DO SOMETHING..
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用系统线程;
名称空间控制台App6
{
班级计划
{
静态void Main(字符串[]参数)
{
int x=10;
线程t1=新线程(新的参数化线程启动(order1));
t1.启动(x);
线程t2=新线程(顺序2);
t2.优先级=线程优先级。最高;
t2.Start();
Console.ReadKey();
}//主要
静态无效顺序1(对象参数)
{
int x=(int)args;
对于(int i=0;i0;i--)
{
Console.ForegroundColor=ConsoleColor.Red;
Console.Write(i.ToString()+);
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用系统线程;
名称空间控制台App6
{
班级计划
{
静态void Main(字符串[]参数)
{
int x=10;
线程t1=新线程(新的参数化线程启动(order1));
t1.IsBackground=true;//我可以停止
t1.启动(x);
线程t2=新线程(顺序2);
t2.优先级=线程优先级。最高;
t2.Start();
Console.ReadKey();
}//主要
静态无效顺序1(对象参数)
{
int x=(int)args;
对于(int i=0;i0;i--)
{
Console.ForegroundColor=ConsoleColor.Red;
Console.Write(i.ToString()+);
}
}`在这里输入代码`
}
}

正如在这里的各种答案中已经提到的那样,该类当前(4.7.2)提供了几个和一个带有重载的方法

本问题的相关施工人员如下:

public Thread(ThreadStart start);

可以接受委托,也可以接受委托

相应的代理如下所示:

public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);
private void Work(object data)
{
   ...
}
public class ThreadWithState
{
    private string message;

    public ThreadWithState(string message)
    {
        this.message = message;
    }

    public void Work()
    {
        Console.WriteLine($"I, the thread write: {this.message}");
    }
}
ThreadWithState tws = new ThreadWithState("I've got some text");
Thread thread = new Thread(tws.Work);

thread.Start();
Thread thread = new Thread( (param) => {
    string name = param as string;
    // rest of code goes here.
});
thread.Start("MyName");
可以看出,要使用的正确构造函数似乎是接受
ParameterizedThreadStart
委托的构造函数,以便线程可以启动符合委托指定签名的某些方法

实例化
线程
类的一个简单示例是

Thread thread = new Thread(new ParameterizedThreadStart(Work));
或者只是

Thread thread = new Thread(Work);
相应方法(本例中称为
Work
)的签名如下所示:

public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);
private void Work(object data)
{
   ...
}
public class ThreadWithState
{
    private string message;

    public ThreadWithState(string message)
    {
        this.message = message;
    }

    public void Work()
    {
        Console.WriteLine($"I, the thread write: {this.message}");
    }
}
ThreadWithState tws = new ThreadWithState("I've got some text");
Thread thread = new Thread(tws.Work);

thread.Start();
Thread thread = new Thread( (param) => {
    string name = param as string;
    // rest of code goes here.
});
thread.Start("MyName");
剩下的就是开始线程。这是通过使用

public void Start();

Start()
将启动线程并将
null
作为数据传递给方法时,
Start(…)
可用于将任何内容传递到线程的
Work
方法中

然而,这种方法存在一个大问题: 传递到
Work
方法的所有内容都被强制转换为对象。这意味着在
Work
方法中,必须再次将其转换为原始类型,如以下示例所示:

public static void Main(string[] args)
{
    Thread thread = new Thread(Work);

    thread.Start("I've got some text");
    Console.ReadLine();
}

private static void Work(object data)
{
    string message = (string)data; // Wow, this is ugly

    Console.WriteLine($"I, the thread write: {message}");
}
    public static void Main()
    {
        List<Task> tasks = new List<Task>();

        Console.WriteLine("Awaiting threads to finished...");

        string par1 = "foo";
        string par2 = "boo";
        int par3 = 3;

        for (int i = 0; i < 1000; i++)
        {
            tasks.Add(Task.Run(() => Calculate(par1, par2, par3))); 
        }

        Task.WaitAll(tasks.ToArray());

        Console.WriteLine("All threads finished!");
    }

    static bool Calculate1(string par1, string par2, int par3)
    {
        lock(_locker)
        {
            //...
            return true;
        }
    }

    // if need to lock, use this:
    private static Object _locker = new Object();"

    static bool Calculate2(string par1, string par2, int par3)
    {
        lock(_locker)
        {
            //...
            return true;
        }
    }


铸造是你通常不想做的事情。

如果有人传递的不是字符串的东西怎么办?因为一开始这似乎是不可能的(因为这是我的方法,我知道我在做什么,或者这个方法是私有的,有人怎么能把任何东西传递给它呢?)你可能会因为各种各样的原因而得到这样的结果。由于某些情况可能不是问题,其他情况则是。在这种情况下,你可能会得到一个你可能不会注意到的结果,因为它只是一个终止符