将参数传递给线程

6

我想在C#的ThreadStart构造函数中传递一个带参数的函数,但是似乎这是不可能的,因为如果我尝试像这样做,就会得到语法错误:

Thread t1 = new Thread(new ThreadStart(func1(obj1));

假设obj1是一个类型为List<string>的对象。

如果我想让一个线程执行这个需要传入对象参数的函数,并且我计划同时创建2个这样的线程,每个线程都有不同的参数值,那么最好的方法是什么?


1
你正在使用哪个版本的.NET? - Mark Byers
哇!我以前是通过创建一个包含线程将使用的数据的类来完成这个任务的,但我不知道有这么多不同的方法可以解决这个问题! - Vivian River
9个回答

13

如果您正在使用.NET 3.5或更高版本,则可以使用lambda表达式来实现此操作:

var myThread = new System.Threading.Thread(() => func1(obj1)); 

8

要将参数传递给线程,您需要使用ParametrizedThreadStart

Thread t1 = new Thread(new ParametrizedThreadStart(func1);
t1.Start(obj1);

非常感谢,这个方法可行。然而,在这种情况下,func1的定义将不得不是 void func1(object state) 而不能是 void func1(List<string> obj1) 为什么会这样呢? - assassin
这就是 ParametrizedThreadStart 委托类型的定义方式。你需要在 func1 中将 object 强制转换回 List<string> - Thomas

7
您可以这样开始一个新线程:
Thread thread = new Thread(delegate() {
    // Code here.
});
thread.Start();

匿名方法 中,您可以访问在创建委托时处于作用域中的变量。


3

试试这个:

var bar = 0.0;
Thread t = new Thread(() => 
    {
        Foo(bar);
    });
t.IsBackground = true;
t.Start();

在你的情况下:

Object obj1 = new Object();
Thread t = new Thread(() => 
    {
        func1(obj1);
    });
t.IsBackground = true;
t.Start();

3

这是您想要的效果吗?

        static void Main(string[] args)
    {
        var list = new List<string>(){
            "a","b","c"
        };

        Thread t1 = new Thread(new ParameterizedThreadStart(DoWork));

        t1.Start(list);

        Console.ReadLine();

    }

    public static void DoWork(object stuff)
    {
        foreach (var item in stuff as List<string>)
        {
            Console.WriteLine(item);
        }
    }

3

Assassin在尝试使这段代码正常工作时遇到了麻烦,因此我在本帖末尾包含了一个完整的示例控制台应用程序。



{ // 一些代码
  Thread t1 = new Thread(MyThreadStart);
  t1.Start(theList);
}
void MyThreadStart(object state) { List<string> theList = (List<string>)state; //.. }

这是我的修改:下面是一个完整的控制台应用程序——这个技巧确实有效:


using System;
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { System.Threading.Thread t = new System.Threading.Thread(MyThreadStart); t.Start("Hello"); System.Console.ReadLine(); }
static void MyThreadStart(object state) { System.Console.WriteLine((string)state); } } }

这个不起作用...我试过了...Thomas建议的ParametrizedThreadStart方法可以。 - assassin
@assassin 我向你保证,它是有效的。我已经编辑了我的条目,包括一个控制台应用程序,你可以直接粘贴到Visual Studio中并运行。这个语法从.Net 2.0开始就可用,并且如果你将“new Thread(MyThreadStart)”替换为“new Thread(new delegate”,它仍然可以工作。 - JMarsch

1
static void func1(object parameter)
{
   // Do stuff here.
}

static void Main(string[] args)
{
  List<string> obj1 = new List<string>();
  Thread t1 = new Thread(func1);
  t1.Start(obj1);
}

它在 .Net 2.0 中使用了一个名为 ParameterizedThreadStart 的新委托。你可以在这里阅读相关信息。


0
你是否绝对需要使用一个Thread对象?还是你只是想要多线程处理发生?更“现代”的方法是使用异步委托,如下所示:
private delegate void FuncDelegate(object obj1);
.
.
.
FuncDelegate func = func1;
IAsyncResult result = func.BeginInvoke(obj1, Completed, func);

// do other stuff
.
.
.

private void Completed(IAsyncResult result)
{
    ((FuncDelegate)result.AsyncState).EndInvoke(result);

    // do other cleanup
}

一种更“现代”的方法是在.NET 4 TPL中使用Tasks



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接