Returning a value from thread?

前端 未结 17 2167
不思量自难忘°
不思量自难忘° 2020-11-27 09:45

How do I return a value from a thread?

相关标签:
17条回答
  • 2020-11-27 10:17

    With the latest .NET Framework, it is possible to return a value from a separate thread using a Task, where the Result property blocks the calling thread until the task finishes:

      Task<MyClass> task = Task<MyClass>.Factory.StartNew(() =>
      {
          string s = "my message";
          double d = 3.14159;
          return new MyClass { Name = s, Number = d };
      });
      MyClass test = task.Result;
    

    For details, please see http://msdn.microsoft.com/en-us/library/dd537613(v=vs.110).aspx

    0 讨论(0)
  • 2020-11-27 10:19

    Can use This Code:

     private Object MyThread(Object Data)
          {
            Object response = null;
            Thread newThread = new Thread(() =>
            {
                response = MyFunction(Data);
                //MyFunction Is Function that you Define
            });
            newThread.Start();
            newThread.Join();
            return response;
          }
    
    0 讨论(0)
  • 2020-11-27 10:21

    My favorite class, runs any method on another thread with just 2 lines of code.

    class ThreadedExecuter<T> where T : class
    {
        public delegate void CallBackDelegate(T returnValue);
        public delegate T MethodDelegate();
        private CallBackDelegate callback;
        private MethodDelegate method;
    
        private Thread t;
    
        public ThreadedExecuter(MethodDelegate method, CallBackDelegate callback)
        {
            this.method = method;
            this.callback = callback;
            t = new Thread(this.Process);
        }
        public void Start()
        {
            t.Start();
        }
        public void Abort()
        {
            t.Abort();
            callback(null); //can be left out depending on your needs
        }
        private void Process()
        {
            T stuffReturned = method();
            callback(stuffReturned);
        }
    }
    

    usage

        void startthework()
        {
            ThreadedExecuter<string> executer = new ThreadedExecuter<string>(someLongFunction, longFunctionComplete);
            executer.Start();
        }
        string someLongFunction()
        {
            while(!workComplete)
                WorkWork();
            return resultOfWork;
        }
        void longFunctionComplete(string s)
        {
            PrintWorkComplete(s);
        }
    

    Beware that longFunctionComplete will NOT execute on the same thread as starthework.

    For methods that take parameters you can always use closures, or expand the class.

    0 讨论(0)
  • 2020-11-27 10:22

    If you don't want to use a BackgroundWorker, and just use a regular Thread, then you can fire an event to return data like this:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    
    namespace ThreadWithDataReturnExample
    {
        public partial class Form1 : Form
        {
            private Thread thread1 = null;
    
            public Form1()
            {
                InitializeComponent();
    
                thread1 = new Thread(new ThreadStart(this.threadEntryPoint));
                Thread1Completed += new AsyncCompletedEventHandler(thread1_Thread1Completed);
            }
    
            private void startButton_Click(object sender, EventArgs e)
            {
                thread1.Start();
                //Alternatively, you could pass some object
                //in such as Start(someObject);
                //With apprioriate locking, or protocol where
                //no other threads access the object until
                //an event signals when the thread is complete,
                //any other class with a reference to the object 
                //would be able to access that data.
                //But instead, I'm going to use AsyncCompletedEventArgs 
                //in an event that signals completion
            }
    
            void thread1_Thread1Completed(object sender, AsyncCompletedEventArgs e)
            {
                if (this.InvokeRequired)
                {//marshal the call if we are not on the GUI thread                
                    BeginInvoke(new AsyncCompletedEventHandler(thread1_Thread1Completed),
                      new object[] { sender, e });
                }
                else
                {
                    //display error if error occurred
                    //if no error occurred, process data
                    if (e.Error == null)
                    {//then success
    
                        MessageBox.Show("Worker thread completed successfully");
                        DataYouWantToReturn someData = e.UserState as DataYouWantToReturn;
                        MessageBox.Show("Your data my lord: " + someData.someProperty);
    
                    }
                    else//error
                    {
                        MessageBox.Show("The following error occurred:" + Environment.NewLine + e.Error.ToString());
                    }
                }
            }
    
            #region I would actually move all of this into it's own class
                private void threadEntryPoint()
                {
                    //do a bunch of stuff
    
                    //when you are done:
                    //initialize object with data that you want to return
                    DataYouWantToReturn dataYouWantToReturn = new DataYouWantToReturn();
                    dataYouWantToReturn.someProperty = "more data";
    
                    //signal completion by firing an event
                    OnThread1Completed(new AsyncCompletedEventArgs(null, false, dataYouWantToReturn));
                }
    
                /// <summary>
                /// Occurs when processing has finished or an error occurred.
                /// </summary>
                public event AsyncCompletedEventHandler Thread1Completed;
                protected virtual void OnThread1Completed(AsyncCompletedEventArgs e)
                {
                    //copy locally
                    AsyncCompletedEventHandler handler = Thread1Completed;
                    if (handler != null)
                    {
                        handler(this, e);
                    }
                }
            #endregion
    
        }
    }
    
    0 讨论(0)
  • 2020-11-27 10:22
    class Program
    {
        static void Main(string[] args)
        {
            string returnValue = null;
           new Thread(
              () =>
              {
                  returnValue =test() ; 
              }).Start();
            Console.WriteLine(returnValue);
            Console.ReadKey();
        }
    
        public static string test()
        {
            return "Returning From Thread called method";
        }
    }
    
    0 讨论(0)
  • 2020-11-27 10:24

    Here is a simple example using a delegate ...

    void Main()
    {
       DoIt d1 = Doer.DoThatThang;
       DoIt d2 = Doer.DoThatThang;
    
       IAsyncResult r1 = d1.BeginInvoke( 5, null, null );
       IAsyncResult r2 = d2.BeginInvoke( 10, null, null );
    
       Thread.Sleep( 1000 );
    
       var s1 = d1.EndInvoke( r1 );
       var s2 = d2.EndInvoke( r2 );
    
       s1.Dump(); // You told me 5
       s2.Dump(); // You told me 10
    }
    
    public delegate string DoIt( int x );
    
    public class Doer
    {
      public static string DoThatThang( int x  )
      {
        return "You told me " + x.ToString();
      }
    }
    

    There's a terrific series on threading at Threading in C#.

    0 讨论(0)
提交回复
热议问题