user983738
user983738

Reputation: 1023

How do I return a result from this thread?

I do not really understand the function of ThreadStart. Can anybody give a simple explanation?

I want to return a string from a ThreadStart function in same function name but different call. How do I do it?

Here is my example code:

1st call:

thSystem[index] = new Thread(new ThreadStart(StartProcess()));

2nd call:

StartProcess();

then

public void StartProcess()
{
    //return string
}

Upvotes: 1

Views: 255

Answers (4)

M.Babcock
M.Babcock

Reputation: 18965

You could also accomplish this using a sort of state variable and using the ParameterizedThreadStart delegate option:

Using a state class such as:

public class ThreadState
{
    public string SomeReturnValue { get; set; }
}

and defining your thread processing method like:

public void DoWork(object param)
{
    ThreadState state = param as ThreadState;

    if (state == null)
        throw InvalidCastException(String.Format("Unable to cast type {0} to {1}.", param.GetType().Name, typeof(ThreadState).Name));

    state.SomeReturnValue = "Success";
}

You can then invoke the thread with:

thSystem[index] = new Thread(DoWork);
ThreadState work = new ThreadState();
thSystem[index].Start(work);

And then access the returned value with:

if(work.SomeReturnValue == "Success")
    Console.WriteLine(The thread invocation was successful!");

None of this code has been tested but should be pretty close to a working state as is.

EDIT: Fixed parameter type and included type checking

Upvotes: 0

Thorsten Dittmar
Thorsten Dittmar

Reputation: 56697

To answer your question first: ThreadStart is simply a delegate. This is used to "pass a method" to the thread instance. The method is then executed in the context of the new thread.

There are two types: ThreadStart is for simple methods that take no parameters. ParameterizedThreadStart is used if you want to pass an argument to the thread.

A thread method can not return any values. What you usually do is define a "state object" that you pass to the thread, which can then modify its content (which, by the way, is also the clean way of providing parameters for the thread). After the thread has finished, you get your result.

I know there are easier ways, like BackgroundWorkers or Tasks, but you asked specifically for Threads, so here we go:

We need a simple state object, which will contain the thread's result:

private class ThreadResult
{
    public string Result;
}

Now we need the method that you want to call without using a thread:

public string PerformSomething()
{
    return "Hello World";
}

Now we need the thread method, which will be run in a different thread. We just make this method call the PerformSomething method, and store the result in the state object. Please note that PerformSomething will also be called in the context of the calling thread - so you have to make sure to handle UI updates correctly and make it thread-safe (this goes beyond this topic):

public string StartProcess(object state)
{
    ThreadResult result = (ThreadResult)state;
    result.Result = PerformSomething();
}

Now we start a new thread and make it do something:

ThreadResult myResult = new ThreadResult();
Thread t = new Thread(ParameterizedThreadStart(StartProcess));
t.Start(myResult);

// Wait for the thread to end
t.Join();

// Evaluate the result
Console.WriteLine(myResult.Result);

As it does not make much sense to spawn a thread and then still lock the application to wait for it to finish, we modify this a little. Assume that you're spawning the thread in some method. The thread will then do its work and run another method when it is finished. You can then handle the result asynchronously.

public void SomeMethodThatStartsTheThread()
{
    ThreadResult myResult = new ThreadResult();
    Thread t = new Thread(new ParameterizedThreadStart(StartProcess));
    t.Start(myResult);

    // We can do other work while the thread is running
}

public string StartProcess(object state)
{
    ThreadResult result = (ThreadResult)state;
    result.Result = PerformSomething();

    ThreadIsDone(result);
}

public void ThreadIsDone(ThreadResult result)
{
    // Do stuff you want to do when the thread is done
}

Please note that ThreadIsDone is also called in the context of the thread you spawned in SomeMethodThatStartsTheThread.

Upvotes: 0

Jeff Mercado
Jeff Mercado

Reputation: 134831

You should consider using the Task Parallel Library to do this rather than using the threading API, it will simplify your code a lot. You could wait for the task to complete and access the Result property to retrieve the result when the task completes.

static string StartProcess()
{
    // do stuff...
    return "some string";
}

Task<string> myTask = Task.Factory.StartNew<string>(StartProcess);
myTask.Wait(); // wait for it to complete
string result = myTask.Result; // get the result

A nicer way to do this would be to provide a continuation method that would be executed automatically when it completes.

static string StartProcess()
{
    // do stuff...
    return "some string";
}

// to be executed when the task completes
static void WhenComplete(Task<string> task)
{
    string result = task.Result;
    // do something with result
}

Task myTask = Task.Factory.StartNew<string>(StartProcess)
    .ContinueWith(WhenComplete);
myTask.Wait(); // wait for everything to complete

Upvotes: 1

msarchet
msarchet

Reputation: 15242

What you should do is something like the following

public class Work
{
   Work() { };

   string WorkString { get; set; }

   public void DoWork()
   {
     WorkString = setString;
   }

}

var newWork = new Work;
thSystem[index] = new Thread(new ThreadStart(newWork.DoWork()));


newWork.WorkString;

Upvotes: 0

Related Questions