How to subscribe to TypedEventHandler<T, TArgs> event using IObservable - system.reactive

I was trying the following,
var _connectedAnimation = ConnectedAnimationService.GetForCurrentView().GetAnimation("forwardAnimation");
Observable.FromEvent<TypedEventHandler<ConnectedAnimation, object>, object>(
handler => _connectedAnimation.Completed += handler,
handler => _connectedAnimation.Completed -= handler)
However, when the event is raised I get the runtime exception
System.ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure)
at System.Reactive.ReflectionUtils.CreateDelegate[TDelegate](Object o, MethodInfo method) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Internal\ReflectionUtils.cs:line 24
at System.Reactive.Linq.ObservableImpl.FromEvent`2.GetHand
The completed event is defined as
public sealed class ConnectedAnimation : IConnectedAnimation, IConnectedAnimation2, IConnectedAnimation3
{
/// <summary>Occurs when the animation is finished.</summary>
public extern event TypedEventHandler<ConnectedAnimation, object> IConnectedAnimation.Completed;
}

Since it is not a standard event and also because there are multiple event arguments, we need to create a Tuple. Refer to 4.2.3. Events with multiple parameters in Rx.Net in Action.
Observable.FromEvent<TypedEventHandler<ConnectedAnimation, object>, Tuple<ConnectedAnimation, object>>(
rxHandler => (animation, o)=> rxHandler(Tuple.Create(animation,o)),
handler => _connectedAnimation.Completed += handler,
handler => _connectedAnimation.Completed -= handler)

Related

ReactiveCommand never hooks up the event handler for the canExecute observable

In my test case I can verify that the event handler CollectionChanged gets hooked up correctly. This occurrs when the command is created. In my view model when I do the same thing the event handler is never hooked up. Why is this?
If I make an explicit call to Undo.CanExecute(null) in my view model it will hook up the event handler. I guess I should not have to do this and that something must be wrong with my view model code.
View Model
ActionManager = new ActionManager();
var canUndo = Observable
.FromEventPattern(e => ActionManager.CollectionChanged += e, e => ActionManager.CollectionChanged -= e)
.Select(_ => ActionManager.CanUndo)
;
Undo = ReactiveCommand.CreateAsyncTask(canUndo, UndoAsync);
Test Case
public class MiscTests
{
[Fact]
public void CanExecute()
{
var am = new ActionManager();
var canUndo = Observable
.FromEventPattern(e => am.CollectionChanged += e, e => am.CollectionChanged -= e)
.Select(_ => am.CanUndo);
var command = ReactiveCommand.Create(canUndo);
var action = new CallMethodAction(() => { }, () => { });
var canExecute = command.CanExecute(null);
canExecute.Should().BeFalse();
am.Execute(action);
canExecute = command.CanExecute(null);
canExecute.Should().BeTrue();
}
}
Don't worry, your view model code is most likely correct.
What you managed to observe is a lazy nature of Rx observables in action. Digging the source code of ReactiveCommand constructor reveals that canExecute observable you provide to CreateAsyncTask factory method is not subscribed immediately, but instead Publish is called, which returns IConnectableObservable, which is stored in a private field (this.canExecute). So, the ReactiveCommand starts to actually listen to canExecute changes, when Connect is called on this.canExecute. This happens in CanExecute(object parameter) method.
So, should you explicitly call ReactiveCommand's CanExecute in your ViewModel? No, because this should be done by your View framework when you bind your command to an actual button.

Replace Anonymous Inner Class By Lambda. How does this work?

While sending a SOAP message, i wanted to add some custom headers so i did like below;
JAXBElement<ConfigurationResponse> jaxbElementResponse = (JAXBElement<ConfigurationResponse>) getWebServiceTemplate()
.marshalSendAndReceive(urlToSend,
new ObjectFactory().createConfigurationRequest(request),
new WebServiceMessageCallback() {
#Override
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
SaajSoapMessage soapMessage = (SaajSoapMessage) message;
SoapHeaderElement id = soapMessage.getSoapHeader().addHeaderElement(new QName(uri, localpart, prefix));
id.setText(text);
}
});
But "NetBeans" tell me i can use lambda expr. So if i do the change, it is like,
JAXBElement<ConfigurationResponse> jaxbElementResponse = (JAXBElement<ConfigurationResponse>) getWebServiceTemplate()
.marshalSendAndReceive(urlToSend,
new ObjectFactory().createConfigurationRequest(request), (WebServiceMessage message) -> {
SaajSoapMessage soapMessage = (SaajSoapMessage) message;
SoapHeaderElement id = soapMessage.getSoapHeader().addHeaderElement(new QName(uri, localpart, prefix));
id.setText(text);
});
Are both same? If yes, how this works?
A Lambda expression is syntactical sugar over an anonymous class. A Lambda can be used where ever the type is an functional interface, which is an interface which declares only one abstract method. The Lambda expression provides the implementation of that single method.
For your case the WebServiceMessageCallback is a functional interface. It has the one abstract method: doWithMessage(...). The Lambda expression you created provides the implementation of that method.

Subscribing to a future observable

I have na event-based API (Geolocator) that I want to convert to Rx.
The problem is that some operations require that all events are unsubscribed and I don't want to pass that burdon to the user of the Rx API.
So, the user will subscribe to a few observables and when the events are subscribed they are published to those observables.
What's the best way to do this?
I thought of creating a subject that the users subscribe to and then have the events published to those through another set of observables.
Is this the best way? If so, how?
The key problem is to find a way to keep an Observer subscribed to a stream whilst tearing down and replacing an underlying source. Let's just focus on a single event source - you should be able to extrapolate from that.
First of all, here is an example class we can use that has a single event SomeEvent that follows the standard .NET pattern using an EventHandler<StringEventArgs> delegate. We will use this to create sources of events.
Note I have intercepted the event add/remove handlers in order to show you when Rx subscribes and unsubscribes from the events, and given the class a name property to let us track different instances:
public class EventSource
{
private string _sourceName;
public EventSource(string sourceName)
{
_sourceName = sourceName;
}
private event EventHandler<MessageEventArgs> _someEvent;
public event EventHandler<MessageEventArgs> SomeEvent
{
add
{
_someEvent = (EventHandler<MessageEventArgs>)
Delegate.Combine(_someEvent, value);
Console.WriteLine("Subscribed to SomeEvent: " + _sourceName);
}
remove
{
_someEvent = (EventHandler<MessageEventArgs>)
Delegate.Remove(_someEvent, value);
Console.WriteLine("Unsubscribed to SomeEvent: " + _sourceName);
}
}
public void RaiseSomeEvent(string message)
{
var temp = _someEvent;
if(temp != null)
temp(this, new MessageEventArgs(message));
}
}
public class MessageEventArgs : EventArgs
{
public MessageEventArgs(string message)
{
Message = message;
}
public string Message { get; set; }
public override string ToString()
{
return Message;
}
}
Solution Key Idea - StreamSwitcher
Now, here is the heart of the solution. We will use a Subject<IObservable<T>> to create a stream of streams. We can use the Observable.Switch() operator to return only the most recent stream to Observers. Here's the implementation, and an example of usage will follow:
public class StreamSwitcher<T> : IObservable<T>
{
private Subject<IObservable<T>> _publisher;
private IObservable<T> _stream;
public StreamSwitcher()
{
_publisher = new Subject<IObservable<T>>();
_stream = _publisher.Switch();
}
public IDisposable Subscribe(IObserver<T> observer)
{
return _stream.Subscribe(observer);
}
public void Switch(IObservable<T> newStream)
{
_publisher.OnNext(newStream);
}
public void Suspend()
{
_publisher.OnNext(Observable.Never<T>());
}
public void Stop()
{
_publisher.OnNext(Observable.Empty<T>());
_publisher.OnCompleted();
}
}
Usage
With this class you can hook up a new stream on each occasion you want to start events flowing by using the Switch method - which just sends the new event stream to the Subject.
You can unhook events using the Suspend method, which sends an Observable.Never<T>() to the Subject effectively pausing the flow of events.
Finally you can stop altogether by called to Stop to push an Observable.Empty<T>() andOnComplete()` the subject.
The best part is that this technique will cause Rx to do the right thing and properly unsubscribe from the underlying event sources each time you Switch, Suspend or Stop. Note also, that once Stopped no more events will flow, even if you Switch again.
Here's an example program:
static void Main()
{
// create the switch to operate on
// an event type of EventHandler<MessageEventArgs>()
var switcher = new StreamSwitcher<EventPattern<MessageEventArgs>>();
// You can expose switcher using Observable.AsObservable() [see MSDN]
// to hide the implementation but here I just subscribe directly to
// the OnNext and OnCompleted events.
// This is how the end user gets their uninterrupted stream:
switcher.Subscribe(
Console.WriteLine,
() => Console.WriteLine("Done!"));
// Now I'll use the example event source to wire up the underlying
// event for the first time
var source = new EventSource("A");
var sourceObservable = Observable.FromEventPattern<MessageEventArgs>(
h => source.SomeEvent += h,
h => source.SomeEvent -= h);
// And we expose it to our observer with a call to Switch
Console.WriteLine("Subscribing");
switcher.Switch(sourceObservable);
// Raise some events
source.RaiseSomeEvent("1");
source.RaiseSomeEvent("2");
// When we call Suspend, the underlying event is unwired
switcher.Suspend();
Console.WriteLine("Unsubscribed");
// Just to prove it, this is not received by the observer
source.RaiseSomeEvent("3");
// Now pretend we want to start events again
// Just for kicks, we'll use an entirely new source of events
// ... but we don't have to, you could just call Switch(sourceObservable)
// with the previous instance.
source = new EventSource("B");
sourceObservable = Observable.FromEventPattern<MessageEventArgs>(
h => source.SomeEvent += h,
h => source.SomeEvent -= h);
// Switch to the new event stream
Console.WriteLine("Subscribing");
switcher.Switch(sourceObservable);
// Prove it works
source.RaiseSomeEvent("3");
source.RaiseSomeEvent("4");
// Finally unsubscribe
switcher.Stop();
}
This gives output like this:
Subscribing
Subscribed to SomeEvent: A
1
2
Unsubscribed to SomeEvent: A
Unsubscribed
Subscribing
Subscribed to SomeEvent: B
3
4
Unsubscribed to SomeEvent: B
Done!
Note it doesn't matter when the end user subscribes - I did it up front, but they can Subscribe any time and they'll start getting events at that point.
Hope that helps! Of course you'll need to pull together the various event types of the Geolocator API into a single convenient wrapper - but this should enable you to get there.
If you have several events you want to combine into a single stream using this technique, look at operators like Merge, which requires you to project the source streams into a common type, with Select maybe, or something like CombineLatest - this part of the problem shouldn't be too tricky.
This is what I came up with.
I have created two subjects for the clients of my API to subscribe:
private readonly Subject<Geoposition> positionSubject = new Subject<Geoposition>();
private readonly Subject<PositionStatus> statusSubject = new Subject<PositionStatus>();
And observables for the events my API is subscribing to:
private IDisposable positionObservable;
private IDisposable statusObservable;
When I want to subscribe to the events, I just subscribe them into the subjects:
this.positionObservable = Observable
.FromEvent<TypedEventHandler<Geolocator, PositionChangedEventArgs>, PositionChangedEventArgs>(
conversion: handler => (s, e) => handler(e),
addHandler: handler => this.geolocator.PositionChanged += handler,
removeHandler: handler => this.geolocator.PositionChanged -= handler)
.Select(e => e.Position)
.Subscribe(
onNext: this.positionSubject.OnNext,
onError: this.positionSubject.OnError);
this.statusObservable = Observable
.FromEvent<TypedEventHandler<Geolocator, StatusChangedEventArgs>, StatusChangedEventArgs>(
conversion: handler => (s, e) => handler(e),
addHandler: handler => this.geolocator.StatusChanged += handler,
removeHandler: handler => this.geolocator.StatusChanged -= handler)
.Select(e => e.Status)
.Subscribe(
onNext: this.statusSubject.OnNext,
onError: this.statusSubject.OnError);
When I want to cancel the subscription, I just dispose of the subscriptions:
this.positionObservable.Dispose();
this.statusObservable.Dispose();

How to communicate user defined objects and exceptions between Service and UI in JavaFX2?

How to communicate user defined objects and user defined (checked) exceptions between Service and UI in JavaFX2?
The examples only show String being sent in to the Service as a property and array of observable Strings being sent back to the UI.
Properties seem to be defined only for simple types. StringProperty, IntegerProperty, DoubleProperty etc.
Currently I have a user defined object (not a simple type), that I want Task to operate upon and update with the output data it produced. I am sending it through the constructor of Service which passes it on through the constructor of Task. I wondered about the stricture that parameters must be passed in via properties.
Also if an exception is thrown during Task's operation, How would it be passed from Service to the UI? I see only a getException() method, no traditional throw/catch.
Properties http://docs.oracle.com/javafx/2/binding/jfxpub-binding.htm
Service and Task http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
Service javadocs http://docs.oracle.com/javafx/2/api/javafx/concurrent/Service.html#getException()
"Because the Task is designed for use with JavaFX GUI applications, it
ensures that every change to its public properties, as well as change
notifications for state, errors, and for event handlers, all occur on
the main JavaFX application thread. Accessing these properties from a
background thread (including the call() method) will result in runtime
exceptions being raised.
It is strongly encouraged that all Tasks be initialized with immutable
state upon which the Task will operate. This should be done by
providing a Task constructor which takes the parameters necessary for
execution of the Task. Immutable state makes it easy and safe to use
from any thread and ensures correctness in the presence of multiple
threads."
But if my UI only touches the object after Task is done, then it should be ok, right?
Service has a signature Service<V> the <V> is a generic type parameter used to specify the type of the return object from the service's supplied task.
Let's say you want to define a service which returns a user defined object of type Foo, then you can do it like this:
class FooGenerator extends Service<Foo> {
protected Task createTask() {
return new Task<Foo>() {
protected Foo call() throws Exception {
return new Foo();
}
};
}
}
To use the service:
FooGenerator fooGenerator = new FooGenerator();
fooGenerator.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override public void handle(WorkerStateEvent t) {
Foo myNewFoo = fooGenerator.getValue();
System.out.println(myNewFoo);
}
});
fooGenerator.start();
If you want to pass an input value into the service each time before you start or restart it, you have to be a little bit more careful. You can add the values you want to input to the service as settable members on the service. These setters can be called from the JavaFX application thread, before the service's start method is invoked. Then, when the service's task is created, pass the parameters through to the service's Task's constructor.
When doing this it is best to make all information passable back and forth between threads immutable. For the example below, a Foo object is passed as an input parameter to the service and a Foo object based on the input received as an output of the service. But the state of Foo itself is only initialized in it's constructor - the instances of Foo are immutable and cannot be changed once created and all of it's member variables are final and cannot change. This makes it much easier to reason about the program, as you never need worry that another thread might overwrite the state concurrently. It seems a little bit complicated, but it does make everything very safe.
class FooModifier extends Service<Foo> {
private Foo foo;
void setFoo(Foo foo) { this.foo = foo; }
#Override protected Task createTask() {
return new FooModifierTask(foo);
}
private class FooModifierTask extends Task<Foo> {
final private Foo fooInput;
FooModifierTask(Foo fooInput) { this.fooInput = fooInput; }
#Override protected Foo call() throws Exception {
Thread.currentThread().sleep(1000);
return new Foo(fooInput);
}
}
}
class Foo {
private final int answer;
Foo() { answer = random.nextInt(100); }
Foo(Foo input) { answer = input.getAnswer() + 42; }
public int getAnswer() { return answer; }
}
There is a further example of providing input to a Service in the Service javadoc.
To return a custom user exception from the service, just throw the user exception during the service's task call handler. For example:
class BadFooGenerator extends Service<Foo> {
#Override protected Task createTask() {
return new Task<Foo>() {
#Override protected Foo call() throws Exception {
Thread.currentThread().sleep(1000);
throw new BadFooException();
}
};
}
}
And the exception can be retrieved like this:
BadFooGenerator badFooGenerator = new BadFooGenerator();
badFooGenerator.setOnFailed(new EventHandler<WorkerStateEvent>() {
#Override public void handle(WorkerStateEvent t) {
Throwable ouch = badFooGenerator.getException();
System.out.println(ouch.getClass().getName() + " -> " + ouch.getMessage());
}
});
badFooGenerator.start();
I created a couple of executable samples you can use to try this out.
Properties seem to be defined only for simple types. StringProperty, IntegerProperty, DoubleProperty etc. Currently I have a user defined object (not a simple type), that I want Task to operate upon and update with the output data it produced
If you want a property that can be used for your own classes try SimpleObjectProperty where T could be Exception, or whatever you need.
Also if an exception is thrown during Task's operation, How would it be passed from Service to the UI?
You could set an EventHandler on the Task#onFailedProperty from the UI with the logic with what to do on failure.
But if my UI only touches the object after Task is done, then it should be ok, right?
If you call it from your UI you are sure to be on the javaFX thread so you will be OK. You can assert that you're on the javaFX thread by calling Platform.isFxApplicationThread().

Stop listening to own events?

Is it possible for a class that is subscribed to a certain event class to fire the same event type without listening to it?
Example:
Class A {
EventBus bus = new EventBus();
public A() {
bus.register(this);
bus.post ( new String("event!"));
}
#Subscribe public void consume(String event) {
System.out.println("Got event: "+event);
}
}
You could have your event class include the source of the event (the object that posted the event) and then just ignore any events where the source is this. I'd recommend trying to make your class handle events consistently regardless of the source, though.
No, there isn't. How could EventBus determine where an event originated in the first place?
If you want to ignore certain events, you must include enough information in the event object itself to determine if the event should be ignored.