Reputation: 1023
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
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
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 BackgroundWorker
s or Task
s, but you asked specifically for Thread
s, 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
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
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