Given we have some kind of rudimentary async CQRS setup like the below:
public interface IRequest<TReturn> { }
public interface IRequestHandler<TRequest, TReturn> where TRequest : IRequest<TReturn>
{
Task<TReturn> RequestAsync<TRequest>(TRequest request);
}
public class GetThings : IRequest<string[]> { }
public class GetThingsHandler : IRequestHandler<GetThings, string[]>
{
public async Task<string[]> RequestAsync<TRequest>(TRequest request)
{
await Task.Run(() => Thread.Sleep(200));
return new[] {"Tim", "Tina", "Tyrion"};
}
}
And we have some kind of dependency injection container:
public class Container
{
public object Resolve(Type serviceType)
{
var possibleTypes = new Dictionary<Type, object>();
possibleTypes.Add(typeof(GetThings), new GetThingsHandler());
return possibleTypes[serviceType];
}
}
For our 'RequestBus' implementation, all generic type parameter information is lost, due to being on the other end of a REST style service:
public async Task<object> GetRequest(object o)
{
Type t = o.GetType();
object handler = container.Resolve(t);
var methodInfo = handler.GetType().GetMethod("RequestAsync");
methodInfo = methodInfo.MakeGenericMethod(typeof (object));
Task methodInvocationTask = (Task)methodInfo.Invoke(handler, new[] {o});
await methodInvocationTask;
// Or: return ((dynamic) methodInvocationTask).Result;
return methodInvocationTask.GetType().GetProperty("Result").GetValue(methodInvocationTask);
}
The only thing that is known is that all tasks may return an object and that we can deduce the type of the request and request return type (it is treated as known here for simplicity).
The question is:
Is calling await on the (void) Task before asking for Task.Result actually executing in an async way? Assuming the handler does actual async work is this method going to be properly async?
(Note: these are simplified implementations for the sake of asking a question)
If you await the task then the rest of the method is executed as a continuation of that Task and control is returned to the caller of the current method, so yes, it'll be asynchronous.
That is the point of await after all; to behave asynchronously.
Calling Result on an already completed Task isn't a problem. It will block the current thread until the Task has completed, but as you know it's already completed, that's not a problem.
Related
I have the interface:
public interface IService
{
Task<double> GetData(int id);
}
And I need to use this interface in my class:
//_svc is a Type of IService
public async void Doit()
{
Task<double> task = await _svc.GetData(id);
}
And when I do it, it says that it can't convert type double into Task<double>
Why is this double instead of the task? The interface clearly specifies that this is a task and here I need to get the task, not the value.
If you need the task to handle it yourself, then remove the await that handles it for you.
It is not an answer, but i hope it will help you to understand Tasks a little bit more. For example you have interface with method:
System.Threading.Tasks.Task<string> FindNameAsync(string computerName);
When you call a method from interface, it will be something like this:
var result = await _scv.FindNameAsync(name); //The program will not go to next line, until it becomes result
When it will get result it will go further. And result you can pass to next methods
EDIT
If you want to get statuses you can make little modifications:
System.Threading.Tasks.Task<bool> FindNameAsync(string computerName);
Then you can return true in case of success, in other case - false.
With a little modification you can pass object to method as parameter and save values that you need in it. Or you can return dictionary or turple, and not bool. Little example:
Your method can be like here:
System.Threading.Tasks.Task<bool> FindNameAsync(SomeClass obj);
And you can handle it so:
SomeClass test = new SomeClass();
if(await _scv.FindNameAsync(test))
{
//code for success result
}else
{
//if error happened handle here
}
The interface clearly specifies that this is a task and here I need to get the task, not the value.
When an interface declares a method that returns a Task or Task<T> the name of the method should - by convention - also end with "Async": https://msdn.microsoft.com/en-us/library/hh191443
Such a method is expected to be implemented as an async method that returns an object of type T if the return type is declared as Task<T> or nothing at all if the return type is just Task:
public interface IService
{
Task<double> GetDataAsync(int id);
}
public class Service : IService
{
public async Task<double> GetDataAsync(int id)
{
await Task.Delay(1000);
return 1.0;
}
}
You would await such a method:
public class Consumer
{
public async void Doit()
{
IService service = new Service();
double d = await service.GetDataAsync(1);
}
}
Now whether the method actually is implemented as an async method is an implementation detail in the concrete implementation of the interface but it doesn't really matter as far as the consumer of the interface is concerned as you can still always await a method that returns Task or Task (provided that the caller method is marked with the async keyword of course).
You would for example be able to await the following non-async implementation of the method the same way:
public class Service : IService
{
public Task<double> GetDataAsync(int id)
{
return Task.FromResult(1.0);
}
}
So methods that have a return type of Task or Task<T> are meant to be asynchronous and awaited.
You could still store an instance of the method's actual return type in a variable "as usual" though:
public void Doit()
{
IService service = new Service();
Task<double> task = service.GetDataAsync(1);
}
This would however simply call the asynchronous without waiting for its return value which makes it pretty useless to even call the method in the first place. When calling a - by contract and convention asynchronous - method that returns a Task<double> you are interested in getting the double value back asynchronously. You don't really care about the Task object itself if you understand what I mean.
I need to invoke a method that meets the following criteria.
The method may run for hours.
The method may interface with hardware.
The method may request user input (parameter values, confirmation, etc). The request should block the method until input has been received.
I have a prototype implementation that fulfills this criteria using the following design.
Assume a Form exists and contains a Panel.
The IntegerInput class is a UserControl with a TextBox and a Button.
public partial class IntegerInput : UserControl
{
public TaskCompletionSource<int> InputVal = new TaskCompletionSource<int>(0);
public IntegerInput()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int val = 0;
Int32.TryParse(textBox1.Text, out val);
InputVal.SetResult(val);
}
}
The Form1UserInput class is instanced by Form1. The container is a Panel set by Form1 before being provided to the invoking class.
public interface IUserInput
{
Task<int> GetInteger();
}
public class Form1UserInput : IUserInput
{
public Control container;
private IntegerInput integerInput = new IntegerInput();
public IntegerInput IntegerInput { get { return integerInput; } }
public async Task<int> GetInteger()
{
container.Invoke(new Action(() =>
{
container.Controls.Clear();
container.Controls.Add(integerInput);
}));
await integerInput.InputVal.Task;
return integerInput.InputVal.Task.Result;
}
}
The Demo class contains the method I want to invoke.
public class Demo
{
public IUserInput ui;
public async void MethodToInvoke()
{
// Interface with hardware...
// Block waiting on input
int val = await ui.GetInteger();
// Interface with hardware some more...
}
public async void AnotherMethodToInvoke()
{
// Interface with hardware...
// Block waiting on multiple input
int val1 = await ui.getInteger();
int val2 = await ui.getInteger();
// Interface with hardware...
}
}
This is a rough outline of what the invoking class looks like. The call to Task.Run() is accurate for my prototype.
public class Invoker
{
public async Task RunTestAsync(IUserInput ui)
{
object DemoInstance = Activator.CreateInstance(typeof(Demo));
MethodInfo method = typeof(Demo).GetMethod("MethodToInvoke");
object[] args = null;
((IUserInput)DemoInstance).ui = ui;
var t = await Task.Run(() => method.Invoke(DemoInstance, args));
// Report completion information back to Form1
}
}
The Form1 controller class instances the Invoker and calls RunTestAsync passing in an instance of Form1UserInput.
I am aware of some concerns about long running Tasks that may block and what that would mean for ThreadPool resources. However, the ability to invoke multiple methods at once is not provided by the application I am building. It's possible that the application may provide some other limited functionality while the invoked method is running but the current requirements do not specify such functionality in detail. I anticipate that there would only be one long running thread in service at any time.
Is the use of Task.Run() for this type of method invocation a reasonable implementation? If not, what would a more reasonable implementation be that provides for the required criteria? Should I consider a dedicated thread outside of the ThreadPool for this invocation?
Is the use of Task.Run() for this type of method invocation a reasonable implementation?
Assuming that your "interface with hardware" can only be done using synchronous APIs, then yes, Task.Run is fine for that.
However, I would change when it's called. Right now, Task.Run is wrapping an async void method that executes on the thread pool (and uses Invoke to jump back on the UI thread). These are each problematic: Task.Run over async void will seem to complete "early" (i.e., at the first await); and using Invoke indicates that there's some tight coupling going on (UI calls background service which calls UI).
I would replace the async void with async Task and also change where Task.Run is used to avoid Invoke:
public async Task<int> GetInteger()
{
container.Controls.Clear();
container.Controls.Add(integerInput);
// Note: not `Result`, which will wrap exceptions.
return await integerInput.InputVal.Task;
}
public async Task MethodToInvokeAsync()
{
await Task.Run(...); // Interface with hardware...
// Block waiting on input
int val = await ui.GetInteger();
await Task.Run(...); // Interface with hardware some more...
}
var t = await (Task)method.Invoke(DemoInstance, args);
To use this method :
public static Task Run(Action action)
I just write :
void MyMethod(){ //do something }
Task t = Task.Run(new Action(MyMethod));
However I do not understand how to use the following overload
public static Task Run(Func<Task> f)
The msdn mentions that the returned task is "a proxy for the task
returned by f" which is even more confusing to me. What is meant by proxy and how would I call this method?
Func<Task> is simply a function that returns a task. That task is then executed.
So Task Run( Func<Task> f ) returns a Task, whose job is to run another Task (the one created by f). That's what's meant by a "proxy".
However, read the Note on MSDN (emphasis added):
The Run<TResult>(Func<Task<TResult>>) method is used by language compilers to support the async and await keywords. It is not intended to be called directly from user code.
Func<T> is a generic delegate - here's its full signature:
public delegate TResult Func<out TResult>()
As you can see, it represents a function that takes no parameters, and returns an instance of type TResult. In the case of Func<Task>, TResult is Task.
What this means, is that you can do this:
public Task MyAsyncMethod() { ... }
Task.Run(MyAsyncMethod);
This converts your method MyAsyncMethod into a delegate of type Func<Task> and passes it to Task.Run. It's syntactic sugar for Task.Run( new Func<Task>(MyAsyncMethod) );
The msdn mentions that the returned task is "a proxy for the task returned by f" which is even more confusing to me (what is meant by proxy ?)
What this means is that Task.Run will simply wrap the task returned by MyAsyncMethod is another Task.
That signature allows you to provide a method that returns a Task, when you run Task.Run. That is because the last generic argument of a Func<T> is the return value given back by the delegate you provide. Meaning:
public Func<bool> IsValid = this.ValidateUser;
public bool ValidateUser() { return someUser.IsAuthenticated; }
or even just
public Func<bool> IsValidUser = this.User.IsAuthenticated;
Then you can use the delegate as you would any other method, and the delegate will return a bool.
public void Foo()
{
if (!IsValidUser()) throw new InvalidOperationException("Invalid user");
}
You can use parameters that are passed in to the delegate, by providing additional generic types other than the return value.
Func<int, bool> IsUserAgeValid = (age) => return age > 18;
// Invoke the age check
bool result = this.IsUserAgeValid(17);
The thing to remember is that the last generic is always the return type in a Func. If only one generic is provided, then there is no parameters, only a return type.
A Func<Task> allows you to use an awaitable method in your Task.Run call.
This also means that you can await from within the anonymous delegate you provide.
public Task Foo()
{
/* .. do stuff */
}
public void Bar()
{
Task.Run(async () =>
{
await Foo();
/* do additional work */
});
}
and if you don't need to await the call to Foo(), you can just give Task.Run the Foo method.
Task.Run(Foo);
If you find yourself wanting to await the awaitable method given to Task.Run as shown above, it is probably better that you use ContinueWith.
public void Bar()
{
Task.Run(Foo).ContinueWith(foosTaskResult =>
{
/* Do stuff */
});
}
The MSDN documentation saying the the Task returned is a proxy for the Task of f, basically means that
Task returnedTask = Task.Run(Foo);
will set returnedTask to be the Task that was returned by the call to the awaitable Foo() method.
a Func<T> refers to a method which returns T, which in this case is a Task. Thus, to make MyMethod compatible with this particular overload, you would write
Task MyMethod() {...}
Which also means you could make MyMethod and async method, thus
async Task MyMethod() {...}
When referring to a "proxy" this means that the Task returned by Task.Run isn't actually the task returned by MyMethod, but instead wraps it.
I have an application with a factory service to allow construction of instances while resolving the necessary dependency injection. For instance, I use this to construct dialog view models. I have a service interface that looks like this:
public interface IAsyncFactory
{
Task<T> Build<T>() where T: class, IAsyncInitialize;
}
Ideally, what I'd like to have is something like this (pseudo-syntax, as this isn't directly achievable)
public interface IFactory
{
Task<T> Build<T>() where T: class, IAsyncInitialize;
T Build<T>() where T: class, !IAsyncInitialize;
}
The idea here is that if a class supports IAsyncInitialize, I'd like the compiler to resolve to the method that returns Task<T> so that it's obvious from the consuming code that it needs to wait for initialization. If the class does not support IAsyncInitialize, I'd like to return the class directly. The C# syntax doesn't allow this, but is there a different way to achieve what I'm after? The main goal here is to help remind the consumer of the class of the correct way to instantiate it, so that for classes with an asynchronous initialization component, I don't try to use it before it has been initialized.
The closest I can think of is to create separate Build and BuildAsync methods, with a runtime error if you call Build for an IAsyncInitialize type, but this doesn't have the benefit of catching errors at compile time.
In general Microsoft suggests to add async suffix when naming asynchronous methods. Thus, your assumption of creating two methods named as Build and BuildAsync makes sense.
I think there is no way to enforce something like "all types that do not implement IAsyncInitialize shall use Build method instead of BuildAsync" unless you force the developers to mark synchronous methods with another interface like ISynchronousInitialize.
You may try the following;
instead of having to separate methods, just implement one BuildAsync method which has the following signature:
Task<T> BuildAsync<T>() where T: class
In the BuildAsync method check whether T implements IAsyncInitialize. If this is the case, just call related initialization code after creating the object of type T. Otherwise, just create a TaskCompletionSource object and run the synchronous initialization code as if it is asynchronous.
The following approach might not be the best, but I find it very convenient. When both asynchronous and synchronous initializers are available (or possibly can be available), I wrap the synchronous one as asynchronous with Task.FromResult, and only expose the asynchronous method to the client:
public interface IAsyncInitialize
{
Task InitAsync();
int Data { get; }
}
// sync version
class SyncClass : IAsyncInitialize
{
readonly int _data = 1;
public Task InitAsync()
{
return Task.FromResult(true);
}
public int Data { get { return _data; } }
}
// async version
class AsyncClass: IAsyncInitialize
{
int? _data;
public async Task InitAsync()
{
await Task.Delay(1000);
_data = 1;
}
public int Data
{
get
{
if (!_data.HasValue)
throw new ApplicationException("Data uninitalized.");
return _data.Value;
}
}
}
This leaves only the asynchronous version of the factory:
public interface IAsyncFactory
{
// Build can create either SyncClass or AsyncClass
Task<T> Build<T>() where T: class, IAsyncInitialize;
}
Furthermore, I prefer to avoid dedicated initializer methods like InitAsync, and rather expose asynchronous properties directly as tasks:
public interface IAsyncData
{
Task<int> AsyncData { get; }
}
// sync version
class SyncClass : IAsyncData
{
readonly Task<int> _data = Task.FromResult(1);
public Task<int> AsyncData
{
get { return _data; }
}
}
// async versions
class AsyncClass : IAsyncData
{
readonly Task<int> _data = GetDataAsync();
public Task<int> AsyncData
{
get { return _data; }
}
private static async Task<int> GetDataAsync()
{
await Task.Delay(1000);
return 1;
}
}
In either case, it always imposes asynchrony on the client code, i.e.:
var sum = await provider1.AsyncData + await provider2.AsyncData;
However, I don't think it's an issue as the overhead of Task.FromResult and await Task.FromResult for the synchronous version is quite low. I'm going to post some benchmarks.
The approach using asynchronous properties can be further improved with Lazy<T>, e.g. like this:
public class AsyncData<T>
{
readonly Lazy<Task<T>> _data;
// expose async initializer
public AsyncData(Func<Task<T>> asyncInit, bool makeThreadSafe = true)
{
_data = new Lazy<Task<T>>(asyncInit, makeThreadSafe);
}
// expose sync initializer as async
public AsyncData(Func<T> syncInit, bool makeThreadSafe = true)
{
_data = new Lazy<Task<T>>(() =>
Task.FromResult(syncInit()), makeThreadSafe);
}
public Task<T> AsyncValue
{
get { return _data.Value; }
}
}
Please bear with me :-)
I'm struggling with the TPL in c# and am stuck trying to figure out the best way to design a solution for kicking off multiple async tasks, waiting for them to complete, and moving on. My initial POC is below. Each IDataGatherer instance needs to get the data and massage it into a DataObject instance.
I'm unsure of how to handle the continuation from the DownloadStringTaskAsync call such that I can take the result and massage it into a DataObject. ContinueWith wants to be provided a method with void return signature but I feel like the ExtractData method needs to return a Task instance or else I don't have a Task instance to return from the GetDataAsync() method.
I'm also wondering if I need to introduce a TaskCompletionSource in my IDataGatherer instances but how do I hitch that onto the task(s) that are doing the real work - DownloadstringTaskAsync and ExtractData for example?
interface IDataGatherer
{
Task<DataObject> GetDataAsync();
}
class DataObject
{
public string Data { get; set; }
}
class IpGatherer : IDataGatherer
{
private readonly string _url = "http://ip.jsontest.com";
public Task<DataObject> GetDataAsync()
{
var tcs = new TaskCompletionSource<DataObject>(); // Do I need this???
var client = new WebClient();
// stuck here
var task = client.DownloadStringTaskAsync(_url).ContinueWith(ExtractData);
}
private void ExtractData(Task<string> obj)
{
}
}
class Program
{
private static void Main(string[] args)
{
// takes a list of IDataGatherers and waits for them
// all to complete, handles exceptions, etc.
}
}
Designing the solution this way may be over-complicating things so I'm open to suggestions to clean things up or do them more succinctly.
I'm using .NET 4.5
First, you don't need TaskCompletionSource. That's because ContinueWith() can be provided with a method with non-void signature. E.g.:
public Task<DataObject> GetDataAsync()
{
var client = new WebClient();
return client.DownloadStringTaskAsync(_url)
.ContinueWith((Func<Task<string>, DataObject>)ExtractData);
}
private DataObject ExtractData(Task<string> task)
{
return new DataObject(task.Result);
}
(Using Result won't block, because you can be certain the Task will be completed at that point.)
But since you're using DownloadStringTaskAsync(), you're likely on .Net 4.5, which means you can use await. That makes the code even simpler:
public async Task<DataObject> GetDataAsync()
{
var client = new WebClient();
var s = await client.DownloadStringTaskAsync(_url);
return ExtractData(s);
}
private DataObject ExtractData(string s)
{
return new DataObject(s);
}