从Thread.Start()的委托函数访问返回值

我有一个程序通过Thread.Start执行一个方法。 该方法具有我想要访问的返回值。 有没有办法做到这一点? 这是一个抽样……

var someValue = ""; Thread t = new Thread(delegate() { someValue = someObj.methodCall(); }); t.Start(); while (t.isAlive) Thread.Sleep(1000); // Check the value of someValue 

因此,一旦while循环结束,someValue应该被设置 – 但是因为它在另一个线程中执行它不会被设置。 有一种简单的方法可以访问它吗?

当调用者和线程方法共享变量时,您已经可以访问它 – 一旦线程完成,您只需检查someValue

当然,您必须知道线程方法何时完成才有用。 在底部,有两种方法可以做到这一点:

  • 将回调发送到完成后可以执行的线程方法。 您可以传递回调方法someValue 。 如果你不关心回调执行时,你可以使用这种技术。

  • 使用某种WaitHandle (或Thread.Join )。 它们告诉您资源何时准备好或事件已完成。 如果您想要启动一个线程,执行其他操作, 然后等到线程完成再继续之前,此技术很有用。 (换句话说,如果你想要与线程同步备份,那就很有用了,而不是马上。)

我无法重现你的问题,我有相同的代码,我看到了预期的结果。 如果您只是要打开当前线程直到它完成,您可以在线程上调用.Join()并等待确保它已完成执行。

 public partial class Form1 : Form { public Form1() { InitializeComponent(); } string someValue = ""; private void Form1_Load(object sender, EventArgs e) { Thread t = new Thread(delegate() { someValue = "asdf"; }); t.Start(); t.Join(); //while (t.IsAlive) Thread.Sleep(1000); System.Diagnostics.Debug.Print(someValue); } } 

从Thread返回值的一种可能方法是使用上下文类作为参数对象。 它也可用于传递参数并检索结果。

另一方面,如果您可以使用BackgroundWorker类,它已经有一个专用的Result对象 – 它的工作方式相同。 但是BackgroundWorker不能用于某些目的(例如,它不支持STA Apartment State)。

请记住,在线程完成之前不应该从ctx.Result读取(ietIsAlive == false)。

  void runThread() { ThreadContext ctx = new ThreadContext(); ctx.Value = 8; Thread t = new Thread(new ParameterizedThreadStart(MyThread)); //t.SetApartmentState(ApartmentState.STA); // required for some purposes t.Start(ctx); // ... t.Join(); Console.WriteLine(ctx.Result); } private static void MyThread(object threadParam) { ThreadContext context = (ThreadContext)threadParam; context.Result = context.Value * 4; // compute result } class ThreadContext { public int Value { get; set; } public int Result { get; set; } } 

您可以使用委托回调从Thread函数检索数据。 委托可以充当线程和调用者之间的桥梁。 例如:

 public delegate void DelReturnValue(string value); public class SayHello { private string _name; private DelReturnValue _delReturnValue; public SayHello(string name, DelReturnValue delReturnValue) { _name = name; _delReturnValue = delReturnValue; } public void SayHelloMethod() { _delReturnValue(_name); } } public class Caller { private static string _returnedValue; public static void ReturnValue(string value) { _returnedValue = value; } public static void Main() { DelReturnValue delReturnValue=new DelReturnValue(ReturnValue); SayHello sayHello = new SayHello("test", delReturnValue); Thread newThread = new Thread(new ThreadStart(sayHello.SayHelloMethod)); newThread.Start(); Thread.Sleep(1000); Console.WriteLine("value is returned: " + _returnedValue); } } 

看看异步编程模型 。

在模型描述的一种常见模式中,您的类将公开BeginXXX和EndXXX方法。 前者启动异步操作并返回IAsyncResult对象。 后者接受IAsyncResult对象作为参数,阻塞调用线程直到操作完成并返回所需的值。