Let's say I have an interface:
interface ILoader()
{
Task<Data> LoadAsync(int id);
}
I have two implementations of this interface:
class NiceDataBase : ILoader
{
public async Task<Data> LoadAsync(int id)
{
//this database has async way of fetching the data
return await NiceDataBaseDriver.LoadDataAsync(id);
}
}
class NotNiceDataBase : ILoader
{
public async Task<Data> LoadAsync(int id)
{
//this database's driver does not have aysnc methods, because it's old or done poorly.
return await Task.Run(() => NotNiceDataBaseDriver.LoadData(id));
}
}
The NotNiceDataBase doesn't provide real async way to load the data, that's why I actually run it on a new thread, which, as I understand, is not really async, because real async does not use a new thread. Is my implementation of NotNiceDataBase a good one then? It kind of cheats the user to think that he is running a real async operation.
What is the optimal way to deal with such situation? I think that the client of NotNiceDataBase should be completely aware what he is doing, otherwise he can't control performance of hiw application well.
My interface could have additional Load method. But in such case, what's the real benefit here? Still LoadAsync of NotNiceDataBase would need to have some implementation. Throwing NotImplementedException is never a good solution I think.
As you know async is an implementation detail and you can not define async on interfaces. So all you have to do is
public class NotNiceDataBase : ILoader
{
public Task<Data> LoadAsync(int id)
{
//this database's driver does not have aysnc methods, because it's old or done poorly.
var result = NotNiceDataBaseDriver.LoadData(id);
return Task.FromResult(result);
}
}
Simply run the method synchronously and return a completed task
e.g.
class NotNiceDataBase : ILoader
{
public Task<Data> LoadAsync(int id)
{
var data = NotNiceDataBaseDriver.LoadData(id);
return Task.From(data);
}
}
You say
I think that the client of NotNiceDataBase should be completely aware
what he is doing, otherwise he can't control performance of hi(s)
application well.
I disagree, if performance is an issue and if they've identified that it's the call to NotNiceDataBase then they can do something about it.
elaboration
Time worrying about how the client is using the interface is almost certainly1 time wasted, and isn't even "premature optimization" but is existential angst over someone else's unknown optimization needs.
1Unless you are your own client, then it's still probably time wasted.
Related
Regarding to this topic and answer I have adapters for my async services registrations :
Async provider in .NET Core DI
And it looks very fine. But I have some services, where I have properties in interface. Properties cant be async, but I need to await client object : var client = await this.connectedClient.Value;
I mean I cant use public bool Connected => (await this.connectedClient.Value).Connected;
What should I do in this case?
public interface IMyAppService
{
bool Connected{ get; }
string Host{ get; }
Task<Data> GetData();
Task SendData(Data data);
}
PS : I dont want to .Result and .GetAwaiter().GetResult() etc. I know Its potentially deadlock there
Given the adapter structure suggested by Steven in the linked question, you can simply implement the Connected property as:
public bool Connected => this.connectedClient.IsValueCreated;
but in the general case, there is no way to run code asynchronously in a property getter or setter.
I need to implement a custom Storage provider for aspnetidentity.
I had a good look round and i found quite a few.However they seem all wrong to me.
My understing is that if you have a method that ends with "async" than it should by asynchronous.
See example taken from somebody's code and this is scattered all over the place.
I find below very misleading since it's not Async at all from what I can see:
public Task<TUser> FindByIdAsync(int userId)
{
TUser result = userTable.GetUserById(userId) as TUser; //this is not async
if (result != null)
{
return Task.FromResult<TUser>(result);
}
return Task.FromResult<TUser>(null);
}
should this be coded like this?:
public async Task<TUser> FindByIdAsync(int userId)
{
TUser result = userTable.GetUserByIdAsync(userId) as TUser;
if (result != null)
{
return await Task.FromResult<TUser>(result);
}
return await Task.FromResult<TUser>(null);
}
Questions?
Is it correct to do "Task.FromResult"? What I mean is does "Task.FromResult actually turns into synchronous? what should it be?
What is the correct way to code the above? what about configureAwait(false)
should async be "All the way down including datalayer to avoid deadlocking"
any sample code /snippet would be appreciated
many thanks for any feedback
The code is not misleading. ASP.NET Identity framework has been designed to provide an asynchronous interface by returning a Task and indicating this by adding the Async suffix to the method name:
Task<TUser> FindByIdAsync(int userId)
However, the underlying provider may not have asynchronous methods. In that case you cannot create an asynchronous implementation but you still have to implement the interface and to do that will have use Task.FromResult exactly as it is done in your first code snippet.
Implementing an asynchronous method using synchronous code
public Task<TUser> FindByIdAsync(int userId)
{
TUser result = userTable.GetUserById(userId) as TUser;
return Task.FromResult<TUser>(result);
}
If your underlying provider supports asynchronous methods you should use async and await.
Implementing an asynchronous method using asynchronous code
public async Task<TUser> FindByIdAsync(int userId)
{
TUser result = (await userTable.GetUserByIdAsync(userId)) as TUser;
return result;
}
Note that Task.FromResult is not used. Task.FromResult is only needed when you have a TResult created by synchronous code and you have to convert it to Task<TResult> required by asynchronous code.
Sometimes your underlying provider can return the desired Task<TUser> without any further work. In that case you can remove the async and await and still provide an asynchronous implementation. This can result in slightly more efficient code:
public Task<TUser> FindByIdAsync(int userId)
{
Task<TUser> result = userTable.GetUserByIdAsync(userId);
return result;
}
The initial code is definitely not asynchronous. It looks like it was put that way to cope with an API design.
However the proposed change doesn't look async to me either. Task.FromResult just creates a completed task with a result, doesn't make anything asynchronous or executes any kind of awaitable code so you should not await on it.
In your case, assuming GetUserByIdAsync returns a Task<TUser>, and assuming the whole purpose of this code (as it seems) is to always return a completed task (never faulted or cancelled), this could be rewritten as:
public async Task<TUser> FindByIdAsync(int userId)
{
var tResult = userTable.GetUserByIdAsync(userId);
TUser result = null;
try
{
result = await tResult;
}
except
{
// Bad idea, but here goes to your first snippet
}
return Task.FromResult<TUser>(result);
}
Note: this is a bad idea as #PanagiotisKanavos commented, it's hiding a possibly faulted state and you won't ever know if your null result came the user not being found, or if there was an error condition: I'd avoid it.
If a faulted/cancelled state is valid, this could simply be:
public Task<TUser> FindByIdAsync(int userId)
{
return userTable.GetUserByIdAsync(userId);
}
An async method is a way for the compiler to build something that will return a promise our future. In the case of the .NET Framework and C#, that is a Task.
The await instruction takes any awaitable and Task just happens to be one. It doesn't know or care if the method/operations being invoked is really asynchronous or not.
Task.FromResult<T> returns a completed task and if you use it in an await instruction inside an async method it will be considered to have been completed synchronously and execution will continue.
So, using async and await with just calls to Task.FromResult<T> ends up just being a waste of CPU cycles and memory by the compiler generating code that will waste more CPU cycles and memory at run time.
Because an async method always returns a Task a decision was made to make it implicit to improve readability and give it some kind of sync feeling. The compile will wrap the return value in a Task. That's why you can't return Task.FromResult<TUser>(result) or Task.FromResult<TUser>(null) directly and are awaiting it to get the value.
So, the async equivalent of your synchronous code would be:
public async Task<TUser> FindByIdAsync(int userId)
{
var result = await userTable.GetUserByIdAsync(userId) as TUser;
if (result != null)
{
return result;
}
return null;
}
Or:
public async Task<TUser> FindByIdAsync(int userId)
{
return await userTable.GetUserByIdAsync(userId) as TUser;
}
I am trying to implement Identity's IUserStore<TUser, in TKey> with NHibernate, which lacks the async methods required by IUserStore. This is my ignorant attempt at dispatching the blocking call and making the method async:
public class QsaasUserStore<TLogin> : IUserStore<QsaasUser<TLogin>, int> where TLogin : QsaasUserLogin<int>
{
public Task CreateAsync(QsaasUser<TLogin> user)
{
var session = NHibertnateSessionProvidser.SessionFactory.GetCurrentSession();
return Task.Factory.StartNew(() => session.Save(user))
.ContinueWith(ex => Trace.TraceError(ex?.Exception?.Message ?? "Strange task fault"), TaskContinuationOptions.OnlyOnFaulted);
}
}
I have gleaned the above from some initial Googling, and it seems OK to me, but I think I could do better with exception handling.
An NHibernate session is not thread-safe.
You are retrieving a session on one thread, and then calling Save on a different thread. This might work, and might even work most of the time, but you are in 'undefined behavior' territory.
The interface you are implementing requires you to return a task. You can fulfill this constraint without involving background threads.
public class QsaasUserStore<TLogin> : IUserStore<QsaasUser<TLogin>, int> where TLogin : QsaasUserLogin<int>
{
public Task CreateAsync(QsaasUser<TLogin> user)
{
var session = NHibertnateSessionProvidser.SessionFactory.GetCurrentSession();
session.Save(user);
return Task.FromResult(0);
}
}
If you really want to run it on a worker thread, then use the background thread to both retrieve the session and call Save. This will only work if your SessionFactory is smart enough to map different sessions to different threads.
public Task CreateAsync(QsaasUser<TLogin> user)
{
return Task.Factory.StartNew(() => {
var session = NHibertnateSessionProvidser.SessionFactory.GetCurrentSession();
session.Save(user);
}).ContinueWith(ex => Trace.TraceError(ex?.Exception?.Message ?? "Strange task fault"), TaskContinuationOptions.OnlyOnFaulted);
}
Are there any issues that I might encounter by wrapping a method that returns a
Task<T> where T : ClassA
with a method that returns a
Task<T> where T : IClassA
In other words wrapping a method that returns a Task of some type with another method that returns a Task of the interface of that type as below:
public new Task<ITspIdentity> FindByIdAsync(string id)
{
return new Task<ITspIdentity>(() => base.FindByIdAsync(id).Result);
}
where base.FindByIdAsync(id) would return
Task<TspIdentity>.
Im having a go at decoupling an ASP.NET MVC applications Presentation tier from a dependency on ASP.Identity by using interfaces.
As long as the calling code doesn't depend on a member that is avaliable only via ClassA and not avaliable via IClassA, there shouldn't be a problem.
You are creating and returning a Cold Task which will run an async method synchronously which is a waste of resources. You can refactor that code and simply do:
public new async Task<ITspIdentity> FindByIdAsync(string id)
{
var tspIdentity = await base.FindByIdAsync(id).ConfigureAwait(false);
return (ITspIdentity) tspIdentity;
}
I'm wondering how to best handle this async await chain where multiple CPU bound methods need to be called sequentially after the async chain.
I've typed up a small example below.
I'm just trying to find out what the best performing / least side effecting pattern is. I want to make sure I'm not defeating the async benefits. My Filter methods do not access anything that is async and awaitable so to make them async means I would have to return Task.Run(() => Filter1(criterion)) in the calling method or something like await Task.Run(() => { return events; }); in the filter methods themselves. Which way to go for a best practice is the question. This is where most discussions stop so a full example and recommendation would be nice.
Are there any 4.5 async await gurus out there who can give good advice?
namespace test
{
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
public class sampleController : ApiController
{
private Service _service;
public sampleController()
{
_service = new Service();
}
public async Task<HttpResponseMessage> SomeTask(DiagnosesSearchCriterion criterion)
{
return Request.CreateResponse<IEnumerable<Diagnosis>>(HttpStatusCode.OK, await _service.GetDiagnosesByGroup(criterion));
}
}
public class Service
{
private Repository _repository;
public Service()
{
_repository = new Repository();
}
public async Task<IEnumerable<Diagnosis>> GetDiagnosis(DiagnosesSearchCriterion criterion)
{
System.IO.Stream events = await _repository.GetEvents(criterion);
// Will these block? Should they be async? They are CPU bound...
// how to best handle this, they need to be called sequentially in most cases.
events = Filter1(criterion, events);
events = Filter2(criterion, events);
return new Diagnosis[]{};
}
public System.IO.Stream Filter1(DiagnosesSearchCriterion criterion, System.IO.Stream events)
{
// CPU bound PLINQ and Parallel filtering logic here.....
return events;
}
public System.IO.Stream Filter2(DiagnosesSearchCriterion criterion, System.IO.Stream events)
{
// CPU bound PLINQ and Parallel filtering logic here.....
// ....
return events;
}
}
public class Repository
{
public async Task<System.IO.Stream> GetEvents(DiagnosesSearchCriterion criterion)
{
WebClient wc = new WebClient();
return await wc.OpenReadTaskAsync("http://www.blah.com/stuff");
}
}
}
On the server side, your primary benefit from async is scalability - that is, the thread pool thread is freed up from handling a request if the request is just waiting for some I/O to complete.
In this case (where your methods are CPU-bound), there's no benefit from making them async. You'll still be taking up a thread pool thread (and adding a small amount of overhead) by using Task.Run. Since they should be executed sequentially, the easiest way to do this is to invoke them synchronously, just like your code is currently doing.
I think this scenario is addressed in the excellent Async in ASP.NET video. Note that this same situation on the client side would be handled differently. On the client side, your primary benefit from async is responsiveness, so it would make sense to toss CPU work into a thread pool thread (Task.Run), since that would free up the UI thread.
(As a side note, it's usually not a good idea to do parallel processing on a server, unless you're sure your user count will be quite low).