Overhead of wrapping synchronous methods in Task.Result - c#

Please consider the following interface example:
public interface ISomeAsyncService<T>
{
Task<T> GetSomeObjectAsync(string id);
}
Now let's assume that some of the implementations of this interface do indeed retrieve objects asynchronously from a data store.
However, other implementations of this service might store objects in memory, for example:
public class SomeService : ISomeAsyncService<MyObject>
{
private static Dictionary<string, MyObject> _dictionary = new Dictionary<string, MyObject>();
public Task<MyObject> GetSomeObjectAsync(string id)
{
var obj = _dictionary[id];
return Task.FromResult(obj);
}
}
I'm doing this to be able to use the same interface for both synchronous and asynchronous services. It is not yet clear which service implementations will use static memory objects, and which will retrieve from a data store.
From what I understand, Task.FromResult will return immediately on the same thread.
Is there no overhead for using this approach as opposed to using synchronous methods (and a different interface) whenever possible? Even when most service calls will end up being to a synchronous implementation?

I've replaced my Task<T> methods with the new C# 7 ValueTask<T> type:
public interface ISomeAsyncService<T>
{
ValueTask<T> GetSomeObjectAsync(string id);
}
This reduces the overhead in case a Task is returning a synchronous result.

Instead of doing Task.FromResult(obj) I would suggest making the method async and just returning obj. That way there is no need to invoke the TaskScheduler in any way.
Here is the complete method.
public class SomeService : ISomeAsyncService<MyObject>
{
private static Dictionary<string, MyObject> _dictionary = new Dictionary<string, MyObject>();
public async Task<MyObject> GetSomeObjectAsync(string id)
{
var obj = _dictionary["id"];
return obj;
}
}

Related

How to dispose the data provider instance using HttpClient?

I have created my data provider using Repository Pattern.
First, I designed a base repository interface as following:
internal interface IGenericRepository<T, in TResourceIdentifier>
{
Task<IEnumerable<T>> GetManyAsync();
Task<T> GetAsync(TResourceIdentifier id);
Task PutAsync(T model);
Task<T> PostAsync(T model);
Task DeleteAsync(TResourceIdentifier id);
}
Then I implemented it:
public class GenericRepository<T, TResourceIdentifier> : IDisposable, IGenericRepository<T, TResourceIdentifier>
where T : class
{
private bool _disposed;
protected HttpClientHelper<T, TResourceIdentifier> Client;
protected GenericRepository(string addressSuffix)
{
Client = new HttpClientHelper<T, TResourceIdentifier>(Properties.Settings.Url, addressSuffix);
}
public async Task<IEnumerable<T>> GetManyAsync()
{
return await Client.GetManyAsync();
}
// All other CRUD methods and dispose
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if(_disposed || !disposing) return;
if(Client != null)
{
var mc = Client;
Client = null;
mc.Dispose();
}
_disposed = true;
}
}
Then I created custom repository interface for each of my entities. For example:
internal interface IOrderRepository : IGenericRepository<Order, int>
{
Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition );
}
And finally, I implemented the custom repository:
public class OrderRepository : GenericRepository<Order, int>, IOrderRepository
{
public OrderRepository(string addressSuffix) : base(addressSuffix)
{
}
public async Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition)
{
//get all the orders (GetManyAsync()) and then returns the ones meeting the condition
}
}
Note that HttpClientHelperuses HttpClient and needs to be disposed manually.
I have created a MVC web application and have defined the repositories at the class level as such:
IOrderRepository _orderRepository = new OrderRepository();
When I call _orderRepository in my CRUD operations, it does not hit dispose after its use. In order to fix that I have ended up implementing like this:
private async Task<IEnumerable<OrderViewModel>> GetOrders()
{
using(var orderRepository = new OrderRepository())
return await orderRepository.GetManyAsync();
}
This would hit the Dispose but is anti pattern.
What am I missing in my implementation that the instance is not disposed on each call?
You should not be disposing HTTPClient after every request.
[https://learn.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests][1]
As the above link says -
Therefore, HttpClient is intended to be instantiated once and reused
throughout the life of an application. Instantiating an HttpClient
class for every request will exhaust the number of sockets available
under heavy loads. That issue will result in SocketException errors.
Possible approaches to solve that problem are based on the creation of
the HttpClient object as singleton or static, as explained in this
Microsoft article on HttpClient usage.
Writing a Dispose method in your generic repository does not mean it will be invoked automatically, whenever you feel like it should. It's intended to be invoked individually, hence why you must either use a using statement (as you have shown), or the Dispose method inside your code.
Alternatively, you can leave that job for the garbage collector.
You should also create a finalizer in your generic repository, if you're convinced on using GC.SuppressFinalize(this);
Read more about that here - When should I use GC.SuppressFinalize()?
As R Jain pointed out, you should also create a static class to hold your HttpClient. You'll have to use HttpResponseMessages for your needs, or HttpContent.
Some more resources to read:
HttpClient single instance with different authentication headers
https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

Getting double instead of the task in C# Task, why?

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.

Implication of calling result on awaited task

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.

Blocking getters while async task completes

I constantly load objects from the database. Usually I would load the object when I need it, and in the constructor I call the database and populate all the methods I need to.
What I had done to speed up this process was create a task in the constructor and use wait before I returned the value in a getter. For example
Before:
class Foo{
public string Bar {get;set;}
public Foo(int id){
DataRow res;
//Do database operations
Bar = res["Bar"].ToString()
}
}
Now:
class Foo{
private Task LoadTask;
private string _Bar;
public string Bar {
get {
LoadTask.Wait();
return _Bar;
}
set {
_Bar = value;
}
}
public Foo(int id){
LoadTask = Task.Factory.StartNew(() => {
DataRow res;
//Do database operations
Bar = res["Bar"].ToString();
});
}
}
What I am wanting to do is extend a class, where in the constructor it fires off this task, calls an overridden method in the sub class and then block any getting of any property until the task completes.
The most I found was this, but not to sure if its what I want at all
http://www.gutgames.com/post/Overridding-a-Property-With-ReflectionEmit.aspx
As I said earlier, I think this design can be improved, but I appreciated the technical challenge so I gave it a shot.
What you talked about sounded not too dissimilar to Entity Framework's dynamically created change tracking proxies, so I had a quick look around for frameworks which work with dynamic proxies and quickly settled on Castle Project (http://www.nuget.org/packages/Castle.Core) as my weapon of choice.
Naive implementation
This is what we're going for at this stage:
Foo foo = Foo.Factory.Create<Foo>();
foo.Bar = "Zzz"; // Runs immediately.
string bar = foo.Bar; // Blocks until initialisation has completed.
Let's leave out inheritance for now (pretend that Foo is sealed).
We want Foo to have no public constructors forcing the consumer to instantiate it via Foo.Factory.Create<Foo>(), which returns a dynamic proxy derived from Foo with an additional bit of functionality injected into every virtual property getter invocation: wait for the initialisation tasks to complete.
using System.Collections.Generic;
using System.Threading.Tasks;
using Castle.DynamicProxy;
public class Foo
{
// Fields.
protected readonly List<Task> InitialisationTasks = new List<Task>();
// Properties.
// These have to be declared virtual
// in order for dynamic proxying to work.
public virtual string Bar { get; set; }
protected Foo()
{
// Initialisation work.
this.InitialisationTasks.Add(Task.Delay(500));
}
// Responsible for instantiating dynamic
// proxies of Foo and its derivatives.
public static class Factory
{
// Static fields.
static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();
static readonly WaitForInitInterceptor Interceptor = new WaitForInitInterceptor();
// Factory method.
public static T Create<T>() where T : Foo
{
return ProxyGenerator.CreateClassProxy<T>(Interceptor);
}
class WaitForInitInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Applies to getters only.
if (invocation.Method.Name.StartsWith("get_"))
{
var foo = invocation.InvocationTarget as Foo;
if (foo != null)
{
// Block until initialisation completes.
Task.WhenAll(foo.InitialisationTasks).Wait();
}
// Continue to the target method.
invocation.Proceed();
}
}
}
}
}
So far so good, but by the sound of it we'll also have to deal with inheritance. The existing design will not support that, because:
the derived class can introduce a public constructor thereby bypassing proxy creation via Foo.Factory.Create<Foo>() - we need to disallow that.
any properties in a derived type need to declared virtual so that their getter invocations can be intercepted by the proxy.
Tweaking to support inheritance
Reflection to the rescue:
public class Foo
{
// Fields.
protected readonly List<Task> InitialisationTasks = new List<Task>();
// Properties.
// These have to be declared virtual
// in order for dynamic proxying to work.
public virtual string Bar { get; set; }
protected Foo()
{
// Enforce proxy integrity.
this.Validate();
// Initialisation work.
this.InitialisationTasks.Add(Task.Delay(500));
}
private void Validate()
{
var type = ProxyUtil.GetUnproxiedType(this);
// No public constructors.
if (type.GetConstructors().Length != 0)
{
throw new InvalidOperationException(
"Public constructors not supported in derived types."
);
}
// No non-virtual properties.
foreach (var property in type.GetProperties())
{
// We're only interested in getters.
var method = property.GetGetMethod();
if (method != null && !method.IsVirtual)
{
throw new InvalidOperationException(
"Only virtual properties are supported."
);
}
}
}
// Responsible for instantiating dynamic
// proxies of Foo and its derivatives.
public static class Factory
{
// Static fields.
static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();
static readonly WaitForInitInterceptor Interceptor = new WaitForInitInterceptor();
// Factory method.
public static T Create<T>() where T : Foo
{
return ProxyGenerator.CreateClassProxy<T>(Interceptor);
}
class WaitForInitInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Applies to getters only.
if (invocation.Method.Name.StartsWith("get_"))
{
var foo = invocation.InvocationTarget as Foo;
if (foo != null)
{
// Block until initialisation completes.
Task.WhenAll(foo.InitialisationTasks).Wait();
}
// Continue to the target method.
invocation.Proceed();
}
}
}
}
}
Now if we were to create class FooDerived : Foo which has a public constructor or non-virtual properties (properties that don't have a getter are exempt from this rule), the base constructor will throw thereby forcing the consumer to use Foo.Factory.Create<FooDerived>().
If FooDerived needs to perform its own asynchronous initialisation work, it can just add its own tasks to InitialisationTasks - any property getter will block until all of them have completed.
This code is a bit rough due to each 'Foo' proxy initialisation doing a lot of intensive work behind the covers (via Validate). In an ideal world I would have some kind of cache (perhaps a dictionary) of types which have already passed the validation, and skip the slow Reflection-bound validation for those.
Alternative approach
While dynamic proxies are fun, the design is flawed. The concerns are not well-separated. Foo shouldn't really be worrying about pulling out its own data in the first place, and definitely shouldn't be worrying about Tasks, thread pool and the like. This was discussed extensively in the comments, and I think your best bet really is to kick off the data loading tasks at the point where you have enough information to do so, save the Task references (or whatever other async unit of work you're using), and then await them (or block by getting Result or calling Wait) when you need to use the fully-loaded instance. This ensures that your Foo instances are not accessible until the loading is fully finished and gives you reasonable control over how the async object loading is scheduled. You could, for example, roll your own limited concurrency scheduler, or use ConcurrentExclusiveSchedulerPairs ExclusiveScheduler to ensure that you are not flooding the thread pool with work. Batching object loading (using Task<IEnumerable<Foo>> instead of IEnumerable<Task<Foo>>, for example) is another good way of keeping tabs on the number of tasks you create. It's easy to get creative with async loading once you decouple it from your object construction logic, and it's almost certainly the right way to go.

Generic constraint based on non-implementation of interface

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; }
}
}

Categories