thread with return type
I have a method which returns a bool
value.
I want to execute that method through Thread
.
Thread t1开发者_StackOverflow = new Thread(new ThreadStart(doThis));
Could you please suggest a way to get that returned value?
Ideally, use the Tasks Parallel Library and Task<T>
instead... but otherwise, you'll need to set up some sort of shared variable to represent the result; when the thread has finished, read the result from whatever thread you need it in.
Another alternative is to use a delegate which returns a bool
and call BeginInvoke
on that delegate to execute it on the thread-pool, returning an IAsyncResult
which will allow you to wait for the result.
If you're just going to wait for the result, why use a thread at all?
bool result = doThis();
Normally with an asynchronous execution, you'd set up a callback to get the result:
Func<bool> handle = doThis;
handle.BeginInvoke(Callback, handle); // asynchronous invocation
// can do more work...
And then you'll get the result in the callback like this:
void Callback(IAsyncResult ar) {
bool result = ((Func<bool>)ar.AsyncState).EndInvoke(ar);
// ...
}
Threads don't have a return value. But there are workarounds such as wrapping the thread in a class. This solution uses an class to store both the method to be executed (indirectly) and stores the returning value. The class can be used for any function and any return type. You just instantiate the object using the return value type and then pass the function to call via a lambda (or delegate).
public class ThreadedMethod<T>
{
private T result;
public T Result
{
get { return result; }
private set { result = value; }
}
public ThreadedMethod()
{
}
//If supporting .net 3.5
public void ExecuteMethod(Func<T> func)
{
Result = func.Invoke();
}
//If supporting only 2.0 use this and
//comment out the other overload
public void ExecuteMethod(Delegate d)
{
Result = (T)d.DynamicInvoke();
}
}
To use this code you can use a Lambda (or a delegate). Here is the example using lambdas:
ThreadedMethod<bool> threadedMethod = new ThreadedMethod<bool>();
Thread workerThread = new Thread((unused) =>
threadedMethod.ExecuteMethod(() =>
SomeMethod()));
workerThread.Start();
workerThread.Join();
if (threadedMethod.Result == false)
{
//do something about it...
}
static void Main(string[] args)
{
bool returnValue = false;
new Thread(
() =>
{
returnValue =test() ;
}).Start();
Console.WriteLine(returnValue);
Console.ReadKey();
}
public static bool test()
{
return true;
}
You can have a member variable that the thread will set, then create an event handle that the thread will set when it completes. You wait on the event handle and then check the bool after the handle is signaled.
I would not suggest you to have a delegate which returns some value. There is a better approach to get some value from a method once it is done with its execution, that is by using "out" parameters.
In your case, you can have something like the code below:
public delegate void DoThisWithReturn(out bool returnValue);
public static void DoThisMethod(out bool returnValue)
{
returnValue = true;
}
public static void Start()
{
var delegateInstance = new DoThisWithReturn(DoThisMethod);
bool returnValue;
var asyncResult = delegateInstance.BeginInvoke(out returnValue, null, null);
//Do Some Work..
delegateInstance.EndInvoke(out returnValue, asyncResult);
var valueRecievedWhenMethodDone = returnValue;
}
public class ThreadExecuter<t> where T : class
{
public delegate void CallBack (T returnValue);
public delegate T Method();
private CallBack callBack;
private Method method;
private Thread t;
public ThreadExecuter(Method _method, CallBack _callBack)
{
this.method = _method;
this.callBack = _callBack;
t = new Thread(this.Process);
}
public void Start()
{
t.Start();
}
public void Abort()
{
t.Abort();
callBack(null);
}
public void Join()
{
t.Join();
}
private void Process()
{
callBack(method());
}
}
usage:
namespace Tester
{
class Program
{
static void Main(string[] args)
{
#region [ Paket Data]
...
#endregion
for (int i = 0; i < 20; i++)
{
Packet packet = new Packet() { Data = data, Host = "www.google.com.tr", Port = 80, Id = i };
SocketManager sm = new SocketManager() { packet = packet };
<b> ThreadExecuter<packet> te = new ThreadExecuter<packet>(sm.Send, writeScreen);
te.Start();</packet></packet></b>
}
Console.WriteLine("bitti.");
Console.ReadKey();
}
private static void writeScreen(Packet p)
{
Console.WriteLine(p.Id + " - " + p.Status.ToString());
}
}
}
Source: http://onerkaya.blogspot.com/2013/04/returning-value-from-thread-net.html
精彩评论