如何在带有参数的线程中调用该方法并返回一些值

我喜欢在带有参数的线程中调用该方法,并在此处返回一些值示例

class Program { static void Main() { Thread FirstThread = new Thread(new ThreadStart(Fun1)); Thread SecondThread = new Thread(new ThreadStart(Fun2)); FirstThread.Start(); SecondThread.Start(); } public static void Fun1() { for (int i = 1; i = 6; i--) { Console.WriteLine("Fun2 writes:{0}", i); } } } 

我知道上面的例子运行成功,但如果方法fun1像这样

 public int fun1(int i,int j) { int k; k=i+j; return k; } 

那怎么能在线程中调用它?

这可能是另一种方法。 这里输入作为参数化传递,并且在委托事件中传递返回类型,这样当线程完成时将调用Delegate。 当线程完成时,这将很好地获得结果。

  public class ThreadObject { public int i; public int j; public int result; public string Name; } public delegate void ResultDelegate(ThreadObject threadObject); public partial class Form1 : Form { public event ResultDelegate resultDelete; public Form1() { InitializeComponent(); resultDelete += new ResultDelegate(resultValue); } void resultValue(ThreadObject threadObject) { MessageBox.Show("Thread Name : " + threadObject.Name + " Thread Value : " + threadObject.result); } private void button1_Click(object sender, EventArgs e) { ThreadObject firstThreadObject = new ThreadObject(); firstThreadObject.i = 0; firstThreadObject.j = 100; firstThreadObject.Name = "First Thread"; Thread firstThread = new Thread(Fun); firstThread.Start(firstThreadObject); ThreadObject secondThreadObject = new ThreadObject(); secondThreadObject.i = 0; secondThreadObject.j = 200; secondThreadObject.Name = "Second Thread"; Thread secondThread = new Thread(Fun); secondThread.Start(secondThreadObject); } private void Fun(object parameter) { ThreadObject threadObject = parameter as ThreadObject; for (; threadObject.i < threadObject.j; threadObject.i++) { threadObject.result += threadObject.i; Thread.Sleep(10); } resultValue(threadObject); } } 

您应该能够使用匿名方法或lambda来提供完整的静态检查:

 Thread FirstThread = new Thread(() => Fun1(5, 12)); 

或者如果你想对结果做些什么:

 Thread FirstThread = new Thread(() => { int i = Fun1(5, 12); // do something with i }); 

但请注意,这个“做某事”仍然在新线程的上下文中运行(但是可以访问外部方法中的其他变量( Main ),由“捕获的变量”提供)。

如果你有C#2.0(而不是上面),那么:

 Thread FirstThread = new Thread((ThreadStart)delegate { Fun1(5, 12); }); 

 Thread FirstThread = new Thread((ThreadStart)delegate { int i = Fun1(5, 12); // do something with i }); 

我喜欢Mark Gravell的回答。 只需稍加修改,您就可以将结果传递回主线程:

 int fun1, fun2; Thread FirstThread = new Thread(() => { fun1 = Fun1(5, 12); }); Thread SecondThread = new Thread(() => { fun2 = Fun2(2, 3); }); FirstThread.Start(); SecondThread.Start(); FirstThread.Join(); SecondThread.Join(); Console.WriteLine("Fun1 returned {0}, Fun2 returned {1}", fun1, fun2); 

在单独的线程中执行函数有更简单的方法:

 // Create function delegate (it can be any delegate) var FunFunc = new Func(fun1); // Start executing function on thread pool with parameters IAsyncResult FunFuncResult = FunFunc.BeginInvoke(1, 5, null, null); // Do some stuff // Wait for asynchronous call completion and get result int Result = FunFunc.EndInvoke(FunFuncResult); 

此函数将在线程池线程上执行,该逻辑对您的应用程序完全透明。 总的来说,我建议在线程池而不是专用线程上执行这样的小任务。

您可以在Thread构造函数上使用ParameterizedThreadStart重载。 它允许您将Object作为参数传递给线程方法。 它将是一个Object参数,所以我通常为这样的线程创建一个参数类。这个对象也可以存储线程执行的结果,你可以在线程结束后读取。

不要忘记在线程运行时访问此对象是可能的,但不是“线程安全”。 你知道该怎么做 :)

这是一个例子:

 void Main() { var thread = new Thread(Fun); var obj = new ThreadObject { i = 1, j = 15, }; thread.Start(obj); thread.Join(); Console.WriteLine(obj.result); } public static void Fun(Object obj) { var threadObj = obj as ThreadObject; threadObj.result = threadObj.i + threadObj.j; } public class ThreadObject { public int i; public int j; public int result; } 

对于一些替代品; 柯里:

 static ThreadStart CurryForFun(int i, int j) { // also needs a target object if Fun1 not static return () => Fun1(i, j); } Thread FirstThread = new Thread(CurryForFun(5, 12)); 

或编写自己的捕获类型(这与编译器为您使用带有捕获变量的anon-methods / lambdas时的操作大致相当,但实现方式不同):

 class MyCaptureClass { private readonly int i, j; int? result; // only available after execution public int Result { get { return result.Value; } } public MyCaptureClass(int i, int j) { this.i = i; this.j = j; } public void Invoke() { // will also need a target object if Fun1 isn't static result = Fun1(i, j); } } ... MyCaptureClass capture = new MyCaptureClass(5, 12); Thread FirstThread = new Thread(capture.Invoke); // then in the future, access capture.Result