Async generic delegate in C# 5.0 - async-ctp

With Iterators, the following generic delegate is possible:
public delegate IEnumerable<TOut> MyDelegate<TIn>(TIn param1);
With the new async/await in C# 5.0 CTP, I expect to be able to create the analogous delegate as follows:
public delegate async TOut MyDelegate<TIn>(TIn param1);
I can't find the C# 5.0 spec or any help in this regard. Anyone know how this can be written or if it can't be written and why?
Thanks!

async is an implementation detail, not an interface specification. An async delegate doesn't make sense.
Any method that returns an "awaitable" (such as Task or Task<T>) can be used with await.
So an "asynchronous delegate" would be any delegate type that returns Task or Task<T> (or any other kind of awaitable). In your case:
public delegate Task<TOut> MyDelegate<TIn, TOut>(TIn param1);

Related

Keep #RequestScoped context when receiving an async CDI event

I want to switch from firing CDI beans synchronous to asynchronous to be able to work stuff parallel.
event.fire(myObject) -> event.fireAsync(myObject)
As I currently use the request context to know what tenant the current process is about, I am confronted with the problem, that the #RequestScoped context is lost in a #ObservesAsync method. Therefor I don't know anymore to what db to persist etc. I could provide the necessary information in the cdi event object and recreate the requestcontext manually after recieving, but this would bloat my object and clutter my code.
Is there a way to simply keep the request context for a async cdi event?
Request scoped objects are not required to be thread-safe and usually are not. For that reason, request context is never automatically propagated across threads. For asynchronous events, indeed you should put all the necessary data into the event object.
You are of course not the first person to ask about this. There's been attempts to define an API/SPI for context propagation (MicroProfile Context Propagation, Jakarta Concurrency), including CDI request context, but they only work correctly in case of sequential processing with thread jumps (common in non-blocking/reactive programming). If you try to [ab]use context propagation for concurrent processing, you're signing up for troubles. For the latest discussion about this, see https://github.com/jakartaee/cdi/issues/474
I actually switched to using interfaces. This gives me more control and makes the code more understandable:
abstract class Publisher<T>{
#All
#Inject
private List<EventConsumer<T>> eventConsumers;
#Inject
private ContextInfo contextInfo;
#Inject
private MutableContextInfo mutableContextInfo;
...
public void publishEvent(T event){
String myContextInfo= contextInfo.getMyContextInfo();
eventConsumers.forEach(consumer -> notifyAsync(consumer, receivedObject, myContextInfo))
}
private void notifyAsync(EventConsumer<T> consumer, T object, String myContextInfo) {
Uni.createFrom()
.voidItem()
.subscribeAsCompletionStage()
.thenAccept(voidItem -> notifyConsumer(consumer, object, myContextInfo));
}
/**
* Method needs to be public to be able to activate request context on self invocation
*/
#ActivateRequestContext
public void notifyConsumer(EventConsumer<T> consumer, T object, String myContextInfo) {
mutableContextInfo.setMyContextInfo(myContextInfo);
try {
consumer.onEvent(object);
} catch (RuntimeException ex) {
log.error("Error while promoting object to eventconsumer", ex);
}
}
}

Can asynchron call return to managedbean?

I am working on an application, where we have to establish, that some steps of the now synchronously working program become asynchron. We are using JSF for frontend and we have managedbeans and EJB-s.
After looking a little bit deeper into the topic, I found, that we can not make asynchronous methods in ManagedBeans, because they are not supported, so they will not work in most situations(in theory for nobody, but it worked for some people according to comments).
In theory I know that supporting an asynchronous execution means, that the asynchron funtion exection will happen with a new thread. After I started the asynchronous execution I can call other functions (like println), in the function. So does this mean, that I can call back into the managed beans as well? Or do they not support that part of the asynchronous execution? And if not, why is it not possible?
By call back I meant something like this:
#ManagedBean
#ViewScoped
public class managedBean{
#EJB
private AsynchronClass asychronClass;
public void function(){
asychronClass.callAsynchronFunction(this);
}
public void functionAsynch(){
//do the original things
}
}
#LocalBean
#Stateless
public class AsychronClass{
public void callAsynchronFunction(managedBean mB){
mB.functionAsynch();
}
}

Using Spring AOP 3.1.0 to set service instance using method argument

Hi i am new to Annotation and Spring AOP. below is what i am trying to achieve
public interface Service {
public void process(String ServiceName, Bean bean);
}
public class ServiceImpl1 implements Service{
public void process(String ServiceName, Bean bean) {
/// do something here
}
}
public class ServiceImpl2 implements Service{
public void process(String ServiceName, Bean bean) {
/// do something here
}
}
from other class i would be calling something like
...
public void doSomething(String serviceName, Bean bean){
service.process("ServiceImpl1", bean);
}
...
I can achieve the same by using AroundAdvice and Before advice and intercepting my doSomething method and then instantiate the service object after reading the serviceName.
I there is a better approach for this?
I just need a direction and then i will figure this out.
Thanks
Well, I am guessing what you want to do is have a Before advice that takes the passed in service name, creates an object of appropriate class, then calls the appropriate method on that newly created object. It seems like, to me, you are really looking for more of a Factory pattern, but trying to use AOP to accomplish it.
If you took the Factory pattern, you would create a class called ServiceFactory, which takes some parameters and returns the correct Service implementation for those parameters. You calling code would simply use the Factory to get the right Service at runtime.
Another approach, if you want to stick with more of a DI pattern, might be to create a wrapper class that serves as the "conductor". This might have a Map of service names to Service implementation. You could then inject this wrapper into your code, and even inject the Map into the wrapper. Your calling code would call methods on the wrapper, which would locate the correct, singleton implementation and aggrigate the call to it.
I just feel that using AOP for this is asking for trouble.
You can inject the service impl class using the spring #Autowire annotation. Since u have 2 implementation classes, you can use qualifier to specify which impl needs to b injected.

Preventing a deadlock when calling an async method without using await

I need to call a method returning a Task from within
public override void OnActionExecuting(ActionExecutingContext filterContext)
It wont let me make this method async it throws the following
An asynchronous module or handler completed while an asynchronous
operation was still pending.
and when calling
entityStorage.GetCurrentUser().Result
I get a deadlock. How can I avoid this?
I have been playing around with it coming up with stuff like
entityStorage.GetCurrentUser().Result.ConfigureAwait(false).GetAwaiter().GetResult();
But this isn't working. How can I do it? My solution will need to work with ASP.NET 4 and the Async Targetting Pack, I can't use ASP.NET 4.5 as am deploying to Azure.
The cause of the deadlock is explained here. In short, don't block on async code. You should use ConfigureAwait(false) in your library async code and await the results (not use Result or Wait).
Update: Please vote here for the MVC team to add support for async action filters.
Since await is just syntax sugar for the compiler rewriting a continuation for you, the most 'direct' path would be to take whatever code was going to follow your await and make it a ContinueWith call.
So, something like:
entityStorage.GetCurrentUser().ContinueWith(t =>
{
// do your other stuff here
});
If you MUST convert asynch to synch.
public User GetCurrentUserSynch()
{
return Task.Run(() =>
{
var asyncResult = entityStorage.GetCurrentUser();
while (!asyncResult.IsCompleted)
{
Application.Current.TryFindResource(new object()); // This is for WPF but you can do some other nonsense action of your choosing
}
return asyncResult.Result;
}).Result;
}
Otherwise use #Stephen's answer.

WCF data services proxy class template

I have a vs2010 solution with many project (WPF control library, some business logic etc.)
Currently each library reach the WCF data services using his own Service Reference.
I'm trying to write a new library that will a some kind of a DL to the WCF data service, I want to write it using templates - so I don't need to write the same function to all my entities (~30).
Well I'm getting nowhere..
I started by add a simple Interface like this:
public interface IRepository<T>
{
IQueryable<T> GetAll();
T GetSingle(int id);
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
IQueryable<T> Where(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Update(T entity);
}
I'm trying to implement the interface and I came into issues I have no Idea how to solve
1) in the implementing class how do I tell my context which entity I'm querying
public IQueryable<Region> Where(Expression<Func<T, bool>> predicate)
{
return _context.(something general).Where(predicate);
}
2) Even if I provide the entity
public IQueryable<Region> Where(Expression<Func<T, bool>> predicate)
{
return _context.Region.Where(predicate);
}
I came into casting issues I didn't manage to solve.
well, that's about it.
Thank you
I've been experiencing by the very same problem: it is not possible to declare a WCF contract with open generic types (nor interfaces, by the way). The problem is that this framework does not adhere to some basic good OOP principles and, thus, it causes some frustration to experienced programmers.
For more information about this issue, see the example at msdn.

Resources