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;
}
Related
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 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.
I'm attempting to convert the following method (simplified example) to be asynchronous, as the cacheMissResolver call may be expensive in terms of time (database lookup, network call):
// Synchronous version
public class ThingCache
{
private static readonly object _lockObj;
// ... other stuff
public Thing Get(string key, Func<Thing> cacheMissResolver)
{
if (cache.Contains(key))
return cache[key];
Thing item;
lock(_lockObj)
{
if (cache.Contains(key))
return cache[key];
item = cacheMissResolver();
cache.Add(key, item);
}
return item;
}
}
There are plenty of materials on-line about consuming async methods, but the advice I have found on producing them seems less clear-cut. Given that this is intended to be part of a library, are either of my attempts below correct?
// Asynchronous attempts
public class ThingCache
{
private static readonly SemaphoreSlim _lockObj = new SemaphoreSlim(1);
// ... other stuff
// attempt #1
public async Task<Thing> Get(string key, Func<Thing> cacheMissResolver)
{
if (cache.Contains(key))
return await Task.FromResult(cache[key]);
Thing item;
await _lockObj.WaitAsync();
try
{
if (cache.Contains(key))
return await Task.FromResult(cache[key]);
item = await Task.Run(cacheMissResolver).ConfigureAwait(false);
_cache.Add(key, item);
}
finally
{
_lockObj.Release();
}
return item;
}
// attempt #2
public async Task<Thing> Get(string key, Func<Task<Thing>> cacheMissResolver)
{
if (cache.Contains(key))
return await Task.FromResult(cache[key]);
Thing item;
await _lockObj.WaitAsync();
try
{
if (cache.Contains(key))
return await Task.FromResult(cache[key]);
item = await cacheMissResolver().ConfigureAwait(false);
_cache.Add(key, item);
}
finally
{
_lockObj.Release();
}
return item;
}
}
Is using SemaphoreSlim the correct way to replace a lock statement in an async method? (I can't await in the body of a lock statement.)
Should I make the cacheMissResolver argument of type Func<Task<Thing>> instead? Although this puts the burden of making sure the resolver func is async on the caller (wrapping in Task.Run, I know it will be offloaded to a background thread if it takes a long time).
Thanks.
Is using SemaphoreSlim the correct way to replace a lock statement in an async method?
Yes.
Should I make the cacheMissResolver argument of type Func<Task<Thing>> instead?
Yes. It'll allow the caller to provide an inherently asynchronous operation (such as IO) rather than making this only suitable for work that is long running CPU bound work. (While still supporting CPU bound work by simply having the caller use Task.Run themselves, if that's what they want to do.)
Other than that, just note that there's not point in having await Task.FromResult(...); Wrapping a value in a Task just to immediately unwrap it is pointless. Just use the result directly in such situations, in this case, return the cached value directly. What you're doing isn't really wrong, it's just needlessly complicating/confusing the code.
If your cache is in-memory (it looks like it is), then consider caching the tasks rather than the results. This has a nice side property if two methods request the same key, only a single resolving request is made. Also, since only the cache is locked (and not the resolving operations), you can continue using a simple lock.
public class ThingCache
{
private static readonly object _lockObj;
public async Task<Thing> GetAsync(string key, Func<Task<Thing>> cacheMissResolver)
{
lock (_lockObj)
{
if (cache.Contains(key))
return cache[key];
var task = cacheMissResolver();
_cache.Add(key, task);
}
}
}
However, this will also cache exceptions, which you may not want. One way to avoid this is to permit the exception task to enter the cache initially, but then prune it when the next request is made:
public class ThingCache
{
private static readonly object _lockObj;
public async Task<Thing> GetAsync(string key, Func<Task<Thing>> cacheMissResolver)
{
lock (_lockObj)
{
if (cache.Contains(key))
{
if (cache[key].Status == TaskStatus.RanToCompletion)
return cache[key];
cache.Remove(key);
}
var task = cacheMissResolver();
_cache.Add(key, task);
}
}
}
You may decide this extra check is unnecessary if you have another process pruning the cache periodically.
In C# and TPL (Task Parallel Library), the Task class represents an ongoing work that produces a value of type T.
I'd like to know what is the need for the Task.FromResult method ?
That is: In a scenario where you already have the produced value at hand, what is the need to wrap it back into a Task?
The only thing that comes to mind is that it's used as some adapter for other methods accepting a Task instance.
There are two common use cases I've found:
When you're implementing an interface that allows asynchronous callers, but your implementation is synchronous.
When you're stubbing/mocking asynchronous code for testing.
One example would be a method that makes use of a cache. If the result is already computed, you can return a completed task with the value (using Task.FromResult). If it is not, then you go ahead and return a task representing ongoing work.
Cache Example: Cache Example using Task.FromResult for Pre-computed values
Use it when you want to create an awaitable method without using the async keyword.
I found this example:
public class TextResult : IHttpActionResult
{
string _value;
HttpRequestMessage _request;
public TextResult(string value, HttpRequestMessage request)
{
_value = value;
_request = request;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage()
{
Content = new StringContent(_value),
RequestMessage = _request
};
return Task.FromResult(response);
}
}
Here you are creating your own implementation of the IHttpActionResult interface to be used in a Web Api Action. The ExecuteAsync method is expected to be asynchronous but you don't have to use the async keyword to make it asynchronous and awaitable. Since you already have the result and don't need to await anything it's better to use Task.FromResult.
From msft.com Create pre-computed tasks with Task.FromResult:
This method is useful when you perform an asynchronous operation that returns a Task object, and the result of that Task object is already computed.
Use the Task.FromResult when you want to have a asynchronous operation but sometimes the result is in hand synchronously. You can find a good sample here http://msdn.microsoft.com/en-us/library/hh228607.aspx.
I would argue that you could use Task.FromResult for methods that are synchronous that take a long time to complete while you can do other independent work in your code. Id rather make those methods to call async though. But imagine the situation where you have no control over the code called and you want that implicit parallel processing.
Task.Run() creates an lambda thread, no async is required and returns a type object. In my example, I have multiple tasks running simulatenously awaiting their completion. Once all the tasks have completed, I can cycle through their results. Task.FromResult is used to push a task result not generated by Task.Run()
The Task.FromResult pushs a type object in this case RecordStruct class in Result class. I created to tasks calling the function getData. The Task.WaitAll processes each of the task and push the results into an array of result object of type RecordStruct. I then access the attribute element of the RecordStruct Class as a result
public class RecordStruct
{
public RecordStruct(string _element) {
element = _element;
}
public string element { get;set; }
}
public class TaskCustom
{
public Task<RecordStruct> getData(string phrase)
{
if (phrase == "hello boise")
{
return Task.FromResult(new RecordStruct("Boise is a great place to live"));
}
return Task.Run(() =>
{
return new RecordStruct(phrase);
});
}
}
[Fact]
public async Task TestFactory()
{
TaskCustom obj = new TaskCustom();
List<Task<RecordStruct>> tasks = new List<Task<RecordStruct>>();
tasks.Add(obj.getData("hello world"));
tasks.Add(obj.getData("hello boise"));
Task.WaitAll(tasks.ToArray());
for(int ctr = 0; ctr < tasks.Count; ctr++) {
if (tasks[ctr].Status == TaskStatus.Faulted)
output.WriteLine(" Task fault occurred");
else
{
output.WriteLine("test sent {0}",
tasks[ctr].Result.element);
Assert.True(true);
}
}
}
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);
}