We're moving to .NET 4.5 and I'm considering adding async to my repositories:
interface IRepository<T>
{
T Find(int id);
Task<T> FindAsync(int id);
IEnumerable<T> FindAll();
Task<IEnumerable<T>> FindAllAsync();
...
}
Implementations will likely call DBs, WebServices, etc.
My question is, should I support CancellationToken?
(Don't worry - FindAllAsync() will probably be Rx-based :) )
Well, definitely add async to your repositories. I'm all for async taking over the world. :)
CancellationToken support is another question. I generally do provide it if it's likely to be needed or if the underlying implementation (DB/web services) supports it (in that case, the implementation is so simple I'd rather just provide it).
Note that you can provide an overload without CancellationToken that just calls the primary implementation passing CancellationToken.None. Alternatively, you can give a default value on the interface of new CancellationToken() which is equivalent to CancellationToken.None. I used to use the default value approach all the time but there are some situations (like assigning an Action variable to myRepository.FindAllAsync) where overloads permit method resolution but default values do not.
I was going to ask the same question. I'm starting to think the answer is "only if you believe cancellation is an important scenario". If you believe some repositories will take such a long time that a user or infrastructure service will want to cancel an in-process query, then you should. I can imagine that for a query, though one would think that most updates and inserts would happen very quickly. If they don't, it's likely because of an exceptional condition which would result in a failed (timed out?) task anyway.
Adding the support for CancellationToken will require all callers to provide one, which has a pernicious chaining effect.
Related
I can't find an async version of RemoveRange. It exists, for example, for AddRange. Anyone knows why? It seems odd to me not to have an homogeneous set of commands.
Because it is synchronous operation and providing fake Async method which runs synchronously and returns completed task would be misleading and against async method principles.
EF Core provides async versions only for methods which potentially access database - e.g. Add{Range}, Find, SaveChanges, Dispose, and sync only version for methods which operate purely on state (change tracker) like Attach{Range}, Update{Range}, Remove{Range}.
As of why Add{Range} have async version, the reason is explained in the documentation:
This method is async only to allow special value generators, such as the one used by Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo, to access the database asynchronously.
Firstly i would like to apologize if i could not find anything about what i would like to describe that really solved my problems. This does not mean that i fully searched in the site. Although i have been spending too much time (days). I am also new on here (in the sense that i never wrote/replied to SO users). And i am sorry for my possible english errors.
I have to say i am new to Java EE.
I am working on WildFly 14, using MySQL.
I am now focusing on a JPA problem.
I have a uniqueness constraint. I am doing tests and while performing the uniqueness violation test, from the data source level i get a MySQLIntegrityConstraintViolationException, and that's ok. I have the problem in that the persist() method does not let me catch the exception (i even put Throwable in the clause, but nothing..). I strongly, strictly, need to catch that, in order to manage a crucial procedure (that, indirectly contains the call to .remove()) in my work's code.
By the way, trying to write that exception, the system does not show me the window of the suggested classes/annotations/etc, suggesting me just to create the class "MySQLIntegrityConstraintViolationException". Doesn't working on WildFly, using MySQL, suffice, for having the suggestions?
Not finding the solution, i decided to change: instead of using persist(), i decided to use .createNativeQuery() in which i put as parameter a String describing an insertion in the db. It seems working. Indeed it works (signals uniqueness violation (ok!), does not execute the TRY block code (ok!) and goes into CATCH block (ok!)). But, again, the exception/error is not clear.
Also, when in the code i enter the piece of code that is in charge of managing the catching and then executing what's inside (and i have a .remove(), inside), it raises the exception:
"Transaction is required to perform this operation (either use a transaction or extended persistence context)" --> this referring to my entityManager.remove() execution..
Now i cannot understand.. should not JPA/JTA manage automatically the transactions?
Moreover, trying, later, to put entityManager.getTransaction().begin() (and commit()), it gives me the problem of having tried to manage manually transactions when instead i couldn't.. seems an endless loop..
[edit]: i am working in CMT context, so i am allowed to work with just EntityManager and EntityManagerFactory. I have tried with entityManager.getTransaction().begin() and entityManager.getTransaction().commit() and it hasn't worked.
[edit']: .getTransaction (EntityTransaction object) cannot be used in CMT context, for this reason that didn't work.
[edit'']: i have solved the transaction issue, by means of the transaction management suited for the CMT context: JTA + CMT requires us to manage the transactions with a TRY-CATCH-FINALLY block, in whose TRY body it is needed to put the operation we want to perform on the database and in whose FINALLY body it is needed to put the EntityManager object closing (em.close()). Though, as explained above, i have used em.createNativeQuery(), that, when failing, throws catchable (catchable in my app) exceptions; i would really need to do a roll-back (usage of .createNativeQuery() is temporary) in my work code and use the .persist() method, so i need to know what to do in order to be able to catch that MySQLIntegrityConstraintViolationException.
Thanks so much!
IT SEEMS i have solved the problem.
Rolling back to the use of .persist() (so, discarding createNativeQuery()), putting em.flush() JUST AFTER em.persist(my_entity_object) has helped me, in that, once the uniqueness constraint is violated (see above), the raised exception is now catchable. With the catchable exception, I can now do as described at the beginning of the post.
WARNING: I remind you of the fact that i am new to JavaEE-JPA-JTA. I have been "lucky" because, since my lack of knowledge, i put that instruction (em.flush()) by taking a guess (i don't know how i could think of that). Hence, I would not be able to explain the behaviour; I would appreciate, though, any explanation of what could have happen, of how and when the method flush() is used, and so on and so forth..
Thanks!
Is there any difference between using async methods provided by System.Data.Entity from Entity Framework and wrapping the same non asynchronous methods with a Task.FromResult ?
For example :
private Task<int> GetCountAsync()
{
return this._myDbContext.Set<MyEntity>().CountAsync();
}
and
private Task<int> GetCountAsync()
{
return Task.FromResult(this._myDbContext.Set<MyEntity>().Count());
}
Yes it could, because if the ADO driver implements async methods using the IOCP thread pool (and it does), will not use a worker thread to wait on the operation, instead will use a special waiting mechanism using I/O Completion Ports, in that way, the server should be able to best scale when there's a lot of contention that do long-running operation against IO like a database query does.
Check some article you can find googling:
I/O Completion Ports
IOCP Thread Pooling in C#
Asynchronous Command Execution in ADO.NET 2.0
Took from the last link:
In previous versions of the .NET Framework it was possible to simulate non-blocking execution by using asynchronous delegates or the ThreadPool class; however, those solutions simply blocked another thread in the background, making them far from ideal for cases where it is important to avoid blocking threads...
ADO.NET/SqlClient asynchronous command execution support is based on true asynchronous network I/O under the covers (or non-blocking signaling in the case of shared memory).
...there are no blocked background threads waiting for a particular I/O operation to finish, and we use the overlapped I/O and the input/output completion ports facilities of the Windows 2000/XP/2003 operating systems to make it possible to use a single thread (or a few of them) to handle all the outstanding requests for a given process.
Edit: Move from comment to here to extend the answer regarding the specific problem of Async Repository Pattern:
I think you should expose those Async methods you need, extending the generic repository, avoiding to couple on EF and avoiding task wrapping, adding CountAsync, AddSync, FindAsync, and all sort of methods you need also async.
Check this out ASYNCHRONOUS REPOSITORY PATTERN WITH ENTITY FRAMEWORK 6
Example of repository:
public interface IRepository<T> where T : class
{
Task<int> AddAsync(T t);
Task<int> RemoveAsync(T t);
Task<List<T>> GetAllAsync();
Task<int> UpdateAsync(T t);
Task<int> CountAsync();
Task<T> FindAsync(Expression<Func<T, bool>> match);
Task<List<T>> FindAllAsync(Expression<Func<T, bool>> match);
}
CountAsync implementation:
public async Task<int> CountAsync()
{
return await _dbContext.Set<T>().CountAsync();
}
Directly took from the post to leave here all the contents.
Then you can extend also your generic repository.
Edit: added some useful readings:
Martin Fowler's
Asynchronous Repositories
Implementing the Repository and Unit of Work Patterns in an ASP.NET MVC Application
The Repository Pattern
Generic Unit of Work and Repositories (lightweight fluent) Framework with Sample Northwind ASP.NET MVC 5 Application: Repositories Framework
While I was browsing through the iOS 7 runtime headers, something caught my eye. In the MCNearbyServiceAdvertiser class, part of the Multipeer Connectivity framework, a property called syncQueue is and multiple methods prefixed with sync are defined. Some of the methods both exist in a prefixed and non-prefixed version, such as startAdvertisingPeer and syncStartAdvertisingPeer.
My question is, what would be the purpose of both this property and these prefixed methods, and how are they combined?
(edit: removed the remark that the queue is serial as pointed out by CouchDeveloper, since we cannot know this)
As you know, the implementation is private.
Having a dispatch queue whose name is syncQueue may not mean that this queue is a serial queue. It might be a concurrent queue as well.
We can only have a guess what the startAdvertisingPeer and the "prefixed" version syncStartAdvertisingPeer might mean.
For example, in order to fulfill internal prerequisites startAdvertisingPeer might assume that it is always invoked from an execution context except the syncQueue. That way, it can synchronously dispatch to the syncQueue with invoking syncStartAdvertisingPeer without ending up in a deadlock. On the other hand, syncStartAdvertisingPeer will always assume to execute on the syncQueue, that way guaranteeing concurrency.
But, as stated, we don't know the actual details - it's just a rough guess. Usually, you should read the documentation - and not some private header details to draw a picture in your mind how this class might likely work.
Why SynchronizedCollection<T> does not acquire a lock on SyncObj in explicit implementation of IEnumerable.GetEnumerator()
IEnumerator IEnumerable.GetEnumerator()
{
return this.items.GetEnumerator();
}
Implicit implementation does acquire a lock on SyncOb (verified by reflector).
It could be problem during foreach loop on this collection. One thread might have acquired a lock and the other could try to read it using foreach?
Because there is no way for the class to know when the client code is done using the iterator. Which is one reason that the MSDN Library docs on the System.Collection classes always warn that iterating a collection isn't thread-safe.
Although they appeared to have forgotten to mention that in the article for SynchronizedCollection. The irony...
Modifying the collection while someone's using an iterator is a concurrency violation anyway.
What would your alternative be? Lock the collection when the iterator is acquired, and not unlock it until the iterator is destructed?
I'm going to go ahead and say that this could be a bug (ed: or at least an inconsistency) in the implementation. Reflector shows exactly what you're seeing, that every other explicit implementation calls lock on the SyncRoot given, except for IEnumerable.GetEnumerator().
Perhaps you should submit a ticket at Microsoft Connect.
I believe the reason the implicit GetEnumerator() method calls lock is because List<T>.GetEnumerator() creates a new Enumerator<T> which relies on the private field _version on the list. While I agree with the other posters, that I don't see the use in locking the GetEnumerator() call, but since the constructor of Enumerator<T> relies on non-threadsafe fields, it would make sense to lock. Or at least remain consistent with the implicit implementations.