C# ThreadPool wait on result - c#

I want to have a function to something similar:
public static V callAsyncAndWait<V>(Func<V> func)
{
ThreadPool.QueueUserWorkItem(obj =>
{
V v = func.Invoke();
});
return v;
}
Obviously this code doesn't compile. What I want is to run the Func in another thread and return the result. How can I do that?

I recommend you to use the new .NET 4.0 Task class instead. Here is a tutorial on how to return a result from the execution of Task: http://msdn.microsoft.com/en-us/library/dd537613.aspx
Practically you have a very convenient property called Result, which, upon invocation of the getter, will block until the result is available.

That doesn't make too much sense. If the method is supposed to wait for the task to be finished, then you don't need a separate thread at all.
Something like "call async and notify when done" would make more sense:
void CallAsyncAndNotifyWhenDone<T>(Func<T> func, Action<T> callback)
{
ThreadPool.QueueUserWorkItem(obj =>
{
T result = func();
callback(result);
});
}

You can use async patternt to do it:
public static V callAsyncAndWait<V>(Func<V> func)
{
var asyncResult = func.BeginInvoke(null, null);
asyncresult.AsyncWaitHandle.WaitOne();
return func.EndInvoke(asyncResult);
}

Related

How do i get return value of action running in a thread in C#?

I want to make a function to run stuff in a throw-away thread... aka keep executing stuff without waiting for the function in the line before it to excute.
So i made a little function here...
public static object Do(System.Action Method)
{
object ret;
System.Threading.Thread t = new System.Threading.Thread(() =>
{ret = Method(); });
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
return ret;
}
Looks simple... there is only one problem... i get the following errors
Cannot implicitly convert type 'void' to 'object'
Use of unassigned local variable 'ret'
I don't care about the second because it will fix itself if i just fix the first... but i don't seem to find a solution for the first...
In short:
All i want is to get the return value of the function chosen aka...
I want the following code to work:
string TEST = Do(() => Console.ReadKey()).ToString();
But the method itself is broken.
Action delegate does not return a value.
Use Func<object> to return object from a passed function.
Also in this case the variable will be most likely returned before the function completes.
I recommend using async/await combination instead. In order for your construction to work you would have do something like this:
public static async Task<object> Do(Func<object> Method)
{
object ret = null;
await Task.Run(
() =>
{
ret = Method();
});
return ret;
}
Which boils down to:
public static async Task<object> Do(Func<object> Method)
{
return Task.Run(Method);
}
Example code:
class Program
{
static AutoResetEvent MyThreadCompletedEvent = new AutoResetEvent(false);
static async void MyThread()
{
Console.WriteLine((await MyClass<ConsoleKeyInfo>.Do(Console.ReadKey)).ToString());
MyThreadCompletedEvent.Set();
}
static void Main(string[] args)
{
Task.Run(() => MyThread());
// Do stuff
// Ensure to wait for MyThread to complete
MyThreadCompletedEvent.WaitOne();
}
}
public static class MyClass<T>
{
public static async Task<object> Do(Func<T> Method)
{
return await Task.Run(Method);
}
}
Instead of creating new thread you could do:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(MyClass<ConsoleKeyInfo>.Do(Console.ReadKey));
}
}
public static class MyClass<T>
{
public static object Do(Func<T> Method)
{
return Method();
}
}
From your title:
How do i get return value of action running in a thread in C#?
You can't. If the thread is still running, the "return value" has not yet been computed. It is not available to return, even if you used the correct Func<T> instead of Action<T>.
In other words, the laws of physics in our universe as we currently know them do not allow for retrieving information from the future.
I want the following code to work:
string TEST = Do(() => Console.ReadKey()).ToString();
Assuming you meant TEST to have the value of the pressed key, then you have to wait for the key to be pressed. The same thing would be obtained with:
string TEST = Console.ReadKey().ToString();
(though you probably would want to use the .KeyChar property...)

How to wait for task to complete before repeating it

How I can wait for task to complete before repeating it
List<ushort> IdsInProgress = new List<ushort>();
public async Task<string> RunMyTask(ushort Id)
{
if (IdsInProgress.Contains(Id))
{
//Here Wait previous task to finish
//and then re-run it
return await MyTask(Id);
}
return await MyTask(Id);
}
public Task<string> MyTask(ushort Id)
{
IdsInProgress.Add(Id);
String MyString;
//do something
IdsInProgress.Remove(Id);
return Task.FromResult(MyString);
}
After dasblinkenlight comments about thread-safe and sync I ended up with this solution. Not sure if this is the best way.
I remove IdsInProgress because I don't need it anymore.
private readonly object obj = new object();
public Task<string> MyTask(ushort Id)
{
lock(obj)
{
String MyString;
//do something
return Task.FromResult(MyString);
}
}
Now if I run this method 100 times they would run one after the other.
Based on luaan comment it's better to do this like this
private SemaphoreSlim semaphore = new new SemaphoreSlim(1);
public Task<string> MyTask(ushort Id)
{
semaphore.Wait();
String MyString;
//do something
semaphore.Release();
return Task.FromResult(MyString);
}
I would suggest you take a look at the ISynchronizeInvoke interface.
The interface allows methods to be called from any thread and marshals that call to the proper thread.
As the goal is to synchronously executes tasks, the Invoke method can be used to delegate and marshal the call to the thread that created this object.
Using this method ensures that the process or task is finished before returning.
Implementing this method is quite straightforward:
public object Invoke(Delegate method, object[] args)
{
return method.DynamicInvoke(args);
}
Typically you would use this method as followed: invokerObj.Invoke(MyMethod)
Which executes MyMethod on the thread managed by the object (invokerObj) implementing the ISynchronizeInvoke interface.
The property InvokeRequired and the methods BeginInvoke & EndInvokecan be implemented if you also wish the possibility to asynchronously execute a delegate. A nice demonstration can be found over here.
I hope this explains it a bit more.

Getting Task results from synchronous execution

I'm having a hard time understanding async and the corresponding behavior. This is a model of the program I'm trying to write, and a repro of the problem I'm having:
namespace AsyncTesting
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("starting....");
MyClass myClass = new MyClass();
myClass.DoSomeWork();
Console.WriteLine("ending....");
Console.ReadLine();
}
}
class MyClass
{
public bool DoSomeWork()
{
return GetTrue().Result;
}
Task<bool> GetTrue()
{
return new Task<bool>(() => true);
}
}
}
When I make the GetTrue().Result call, it never returns. My Task<bool> GetTrue() method is a dummy method for repro purposes, but I'm not quite sure why it never comes back. But it returns if I have this:
namespace AsyncTesting
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("starting....");
MyClass myClass = new MyClass();
myClass.DoSomeWork();
Console.WriteLine("ending....");
Console.ReadLine();
}
}
class MyClass
{
public async void DoSomeWork()
{
await GetTrue();
}
Task<bool> GetTrue()
{
return new Task<bool>(() => true);
}
}
}
The problem is, with my repro I want the initial behavior. I don't want async void for the calling method. I want to be able to return bool from my calling "normal" method. How can I achieve this? How can I get the first example to run and actually return the bool from DoSomeWork()?
Thank you in advance.
EDIT: Thank you for the answers. I think what the problem is, is that my GetTrue() method isn't a true repro. In my method, I'm not generating the actual Task<bool> object. It's really a call to Task.Factory.FromAsync<bool>() that is creating the Task<bool> object. And it's that task that I don't know how to "start". Any other ideas? Thanks!
You're probably looking for:
Task<bool> GetTrue()
{
return Task.FromResult(true);
}
instead of:
Task<bool> GetTrue()
{
return new Task<bool>(() => true);
}
In the latter case, you don't even start the task you create. You'd need to start it with Task.Run or Task.RunSynchronously. Usually you don't create tasks directly via new Task(). Check Stephen Toub's "Task.Factory.StartNew" vs "new Task(...).Start" and "Task.Run vs Task.Factory.StartNew".
Depending on what you're trying to achieve, you might be tempted to do this:
Task<bool> GetTrue()
{
return Task.Run(() => true);
}
However, usually this turns to be a known-anti-pattern, check "Should I expose asynchronous wrappers for synchronous methods?".
Updated to address the comments:
... the context is a WCF service. The Task.Factory.FromAsync()
call is wrapping the Begin...() and End...() functions that the
service has pushed to the consumer. But I see no way to actually start
the task and it just hangs.
... it is the client-side making the WCF call. The client-side app is a
Windows Phone 8 application.
You're experiencing a deadlock on the UI thread, because you're blocking on the result of a pending task (with task.Result). The task itself cannot be completed, because the await continuation is posted asynchronously to the dispatcher loop of the UI thread of your WP8 app, which is now blocked. Stephen Cleary explains this in great details in his blog. To avoid this, you should embrace "async all the way down" programming model. It practically means that you should make your UI event and command handlers async as well, and do var result = await task, rather than var result = task.Result in there.
You need to start a task before it does anything.. calling Run will do that for you:
Task<bool> GetTrue()
{
return Task.Run(() => true);
}
This gives the output you expect. Result is a blocking call. If your Task instance never starts.. Result can never return.

Running Tasks generically

In my project I heavily make use of TPL, and I decide to design a generic way of producing tasks, instead of calling new Task(Action);, new Task(Action<object>, object); or Task.Factory.StartNew(Action) etc. explicitly.
I will have a function like
void SpawnTask<A,B>( Action<A,B> action, A a, B b) { ... }
void SpawnTask<A,B,C>( Action<A,B,C> action, A a, B b, C c) { ... }
for creating and starting tasks.
Also I need to run a mandatory method after each task completed. Thus I have to wrap the actual method I want to run in another method like
void RuncTask(Action action)
{
action();
MandatoryMethod();
}
So far I come up with two different approaches.
First, using anonymous delegates:
void SpawnTask<A,B>(Action<A,B> action, A a, B b)
{
A dummyA = a; // To localize the parameters.
B dummyB = b;
var methodDelegate = delegate { action(dummyA,dummyB); };
var taskDelegate = delegate { RunTask(methodDelegate); };
Task.Factory.StartNew( taskDelegate );
}
void RuncTask(Action action)
{
action();
MandatoryMethod();
}
Second, using tuple:
void SpawnTask<A,B>(Action<A,B> action, A a, B b)
{
Tuple<Action<A,B>, A, B> tpl = Tuple.Create(action, a, b);
Action<object> act = RunTask<A,B>;
Task.Factory.StartNew( act, tpl );
}
void RuncTask<A,B>(object obj)
{
var tpl = (Tuple<Action<A, B>, A, B>)param;
tpl.Item1(tpl.Item2,tpl.Item3);
MandatoryMethod();
}
I like the first one because, it is simpler. The second has casting, requires other generic RunTask methods to be implemented for different number of parameters. But I do not know if creating too much anonymous delegates can cause side effects.
Which one do you prefer? Why? Or what other solutions do you have?
Well, you can always create an extension method on Action<TA,TB> ... and you should use continuations rather than wrapped method calls to implement the behavior of always performing another action when the task completes:
public static class TaskExtensions
{
public static void RunTask<TA,TB>( Action<TA,TB> action, TA a, TB b )
{
Task newTask = new Task( () => action(a,b) );
newTask.ContinueWith( MandatoryMethod );
newTask.Start();
}
// if you need to support other signature (more parameters) you would need to
// create additional overloads of RunTask with more generic parameters...
public static void RunTask( Action action );
public static void RunTask<TA>( Action<TA> action, TA a );
// etc ...
private static void MandatoryMethod( Task t ) { /* your continuation logic */ }
}
Now you can use this code as follows:
public void SomeMethod( int x, int y ) { ... }
// later...
Action<int,int> myAction = SomeMethod;
myAction.RunTask( 1, 2 );
Note that in the above implementation the continuation method (MandatoryMethod) will be executed asynchronously. If you desire synchronous execution (as is implemented in your example), you can use the overload of ContinueWith that takes a TaskContinuationOptions and pass in TaskContinuationOptions.ExecuteSynchronously.
Frankly, I mot quite sure what you are trying to accomplish with that. What advantage over directly using Task constructor or Task.Factory are you hoping to achieve?
As for a "mandatory method" that needs to execute after task finishes, look at continuations (e.g. Task.ContinueWith).

Creating a task wrapper around an existing object

I have a method which returns a Task where the implementation may or may not need to perform a slow operation in order to retrieve the result. I would like to be able to simply wrap the result value into a Task which is marked as having completed synchronously in the case where the value is already available. Today I have something like this:
public Task<Foo> GetFooAsync(int key) {
lock(this) {
if(_Cache.ContainsKey(key) ) {
Task<Foo> ret = new Task<Foo>(()=>_Cache[key]);
ret.RunSynchronously();
return ret;
}
else {
return Task.Factory.StartNew<Foo>(SomethingSlow());
}
}
}
Is there is simpler way to do this that doesn't require me to construct the task with a delegate when I already know the result?
Beginning with .NET 4.5, you can use the Task.FromResult<T>() static method for exactly this purpose:
return Task.FromResult(_Cache[key]);
You could use a TaskCompletionSource<TResult>:
var tcs = new TaskCompletionSource<Foo>();
tcs.SetResult(_Cache[key]);
return tcs.Task;
(Note that if _Cache is a Dictionary<TKey, TValue> you could use TryGetValue to make it a single lookup.)
If you have a synchronous version of the method that returns the result you can do the following
Task<String>(()=> Hello(Name));
The hello method would look like below.
public String Hello(String Name)
{
return "Hello " + Name;
}

Categories

Resources