Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a value from thread?

People also ask

How do you return a value from a thread in Python?

format(bar) return 'foo' + baz from multiprocessing. pool import ThreadPool pool = ThreadPool(processes=1) async_result = pool. apply_async(foo, ('world', 'foo')) # tuple of args for foo # do some other stuff in the main process return_val = async_result. get() # get the return value from your function.

Can a thread return a value JAVA?

When creating a multithreaded program, we often implement the runnable interface. Runnable does not have a return value. To get the return value, Java 5 provides a new interface Callable, which can get the return value in the thread.

Can a thread return a value C#?

Threads do not really have return values. However, if you create a delegate, you can invoke it asynchronously via the BeginInvoke method. This will execute the method on a thread pool thread. You can get any return value from such as call via EndInvoke .

How do you return a value from a Posix thread?

If you want to return only status of the thread (say whether the thread completed what it intended to do) then just use pthread_exit or use a return statement to return the value from the thread function.


One of the easiest ways to get a return value from a thread is to use closures. Create a variable that will hold the return value from the thread and then capture it in a lambda expression. Assign the "return" value to this variable from the worker thread and then once that thread ends you can use it from the parent thread.

void Main()
{
  object value = null; // Used to store the return value
  var thread = new Thread(
    () =>
    {
      value = "Hello World"; // Publish the return value
    });
  thread.Start();
  thread.Join();
  Console.WriteLine(value); // Use the return value here
}

It depends on how do you want to create the thread and available .NET version:

.NET 2.0+:

A) You can create the Thread object directly. In this case you could use "closure" - declare variable and capture it using lambda-expression:

object result = null;
Thread thread = new System.Threading.Thread(() => { 
    //Some work...
    result = 42; });
thread.Start();
thread.Join();
Console.WriteLine(result);

B) You can use delegates and IAsyncResult and return value from EndInvoke() method:

delegate object MyFunc();
...
MyFunc x = new MyFunc(() => { 
    //Some work...
    return 42; });
IAsyncResult asyncResult = x.BeginInvoke(null, null);
object result = x.EndInvoke(asyncResult);

C) You can use BackgroundWorker class. In this case you could use captured variable (like with Thread object) or handle RunWorkerCompleted event:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) => {
    //Some work...
    e.Result = 42;
};
worker.RunWorkerCompleted += (s, e) => {
    //e.Result "returned" from thread
    Console.WriteLine(e.Result);
};
worker.RunWorkerAsync();

.NET 4.0+:

Starting with .NET 4.0 you could use Task Parallel Library and Task class to start your threads. Generic class Task<TResult> allows you to get return value from Result property:

//Main thread will be blocked until task thread finishes
//(because of obtaining the value of the Result property)
int result = Task.Factory.StartNew(() => {
    //Some work...
    return 42;}).Result;

.NET 4.5+:

Starting with .NET 4.5 you could also use async/await keywords to return value from task directly instead of obtaining Result property:

int result = await Task.Run(() => {
    //Some work...
    return 42; });

Note: method, which contains the code above shoud be marked with asynckeyword.

For many reasons using of Task Parallel Library is preferable way of working with threads.


I would use the BackgroundWorker approach and return the result in e.Result.

EDIT:

This is commonly associated with WinForms and WPF, but can be used by any type of .NET application. Here's sample code for a console app that uses BackgroundWorker:

using System;
using System.Threading;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;

namespace BGWorker
{
    class Program
    {
        static bool done = false;

        static void Main(string[] args)
        {
            BackgroundWorker bg = new BackgroundWorker();
            bg.DoWork += new DoWorkEventHandler(bg_DoWork);
            bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
            bg.RunWorkerAsync();

            while (!done)
            {
                Console.WriteLine("Waiting in Main, tid " + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(100);
            }
        }

        static void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine("Completed, tid " + Thread.CurrentThread.ManagedThreadId);
            done = true;
        }

        static void bg_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Work Line: " + i + ", tid " + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(500);
            }
        }
    }
}

Output:

Waiting in Main, tid 10
Work Line: 1, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Work Line: 2, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Work Line: 3, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Work Line: 4, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Work Line: 5, tid 6
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Waiting in Main, tid 10
Completed, tid 6

2014 UPDATE

See @Roger's answer below.

https://stackoverflow.com/a/24916747/141172

He points out that you can use a Task that returns a Task<T>, and check Task<T>.Result.


A thread isn't a method - you don't normally "return" a value.

However, if you're trying to fetch a value back from the results of some processing, you have many options, the two main ones being:

  • You can synchronize a shared piece of data, and set it appropriately.
  • You can also pass the data back in some form of callback.

It really depends on how you're creating the thread, and how you want to use it, as well as the language/framework/tools you're using.


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.