I am looking for something I would call CounterObservable One side would count the numbers on it and other side would be the observer side that will receive notification every time total count changes.
In other words I will have something like this
public CounterObservable totalMailsReceived = new CounterObservable(0);
public void OnNewMail(Mail mail)
{
totalMailsReceived++;
///Rest of the code goes here
}
on the Observer side I will have
mailManager.totalMailsReceived.Subscribe(count => labelCount.Text = count.ToString());
Or if I want to go real classy, I would use Paul Betts' ReactiveUI like the following
mailManager.totalMailsReceived.ToProperty(x => x.TotalMailsReceived);
I have so far found nothing in Rx that could help me. But I figured if I create my own class that implements IObservable<int>. I am thinking of leveraging the Sample MSDN Code for IObservable implementation for that.
My questions are
1. Is that MSDN Sample thread-safe ?
2. Is there really nothing in Rx already that does what I am trying to do ?
Just use a BehaviorSubject:
public class MailServer
{
private BehaviorSubject<int> _count = new BehaviorSubject<int>(0);
public IObservable<int> TotalMailsReceived
{
get { return _count; }
}
public void OnNewMail(Mail mail)
{
_count.OnNext(_count.Value + 1);
}
}
Or, if you decide to go deeper into Rx, so that you are just observing a Mail stream, then you can use Scan operator which is good for that and Publish to remember the most recent value and multicast it to all subscribers.
You can write this new extension method:
public IObservable<T> RunningTotal<T>(this IObservable<T> source)
{
return source.Scan(0, sum => sum + 1);
}
And use it like so:
public class MailServer
{
private IConnectableObservable<int> _total;
private IDisposable _subscription;
public MailServer(IObservable<Mail> incomingMail)
{
_total = incomingMail.RunningTotal().Publish(0);
_subscription = _total.Connect();
}
public IObservable<int> TotalMailsReceived
{
get { return _total; }
}
}
Related
I am trying to create a hot observable where I can add stuff to it. Here's an outline of the basic class
public class MyObservable
{
public IObservable<string> Stream;
public MyObservable()
{
Observable.Create...?
}
public void AddString(string eventDescription)
{
//Add to Stream
}
}
Somewhere else in the code I want to be able to do something like
var ob = new MyObservable();
MyObservable.Add("User created");
Then somewhere else something like:
ob.Stream.Subscribe(Console.WriteLine);
I am not really sure how I am supposed to add strings to the observable
edit: I've tried doing something like this, but I'm not sure if maybe I'm not doing things in the way it's supposed to be done
private IObserver<string> _observer;
public void Add(string e)
{
if(Stream == null)
{
Stream = Observable.Create<string>(
(IObserver<string> observer) =>
{
_observer = observer;
observer.OnNext(e);
return Disposable.Empty;
});
}
else
{
_observer.OnNext(e);
}
}
You should do a little more reading on the contracts of observables and observers
Regardless, what you are looking for is a Subject, which implements both the Observable and Observer interfaces.
If you still want to wrap it it would look like so:
public class MyObservable
{
private Subject<string> subject;
public IObservable<string> Stream
{
get { return this.subject.AsObservable();
}
public MyObservable()
{
subject = new Subject<string>();
}
public void AddString(string eventDescription)
{
//Add to Stream
this.subject.OnNext(eventDescription);
}
}
Given an arbitrary field on a Java object, I want to create an Observable that will watch that field and push a new result to an Observer every time the value of the field changes. ReactiveCocoa has a macro called RACObserve, which appears to do exactly this.
I want to know how to implement similar functionality using RxJava.
For example, say I had the following simple class:
public class Foo {
enum State {
Idle,
Ready,
Error
}
private State currentState = State.Idle;
//methods that can change currentState
}
I want to create an Observable<State> that will push the new state to an Observer every time something changes the value of currentState.
In ReactiveCocoa, it looks like I would write something sort of like the following (please excuse my pseudo Objective-C):
[RACObserve(self, currentState) subscribeNext:^(NSString *newState) {
NSLog(#"%#", newState);
}];
How would I achieve similar functionality in RxJava? I'm thinking that I may need to wrap all changes to currentState in a setter, but it's not clear to me where I should then call Observable.create and how to feed the changes of currentState to an Observer.
ReactiveCocoa is actually more similar to ReactiveUI (http://www.reactiveui.net) than just plain Rx. And in ReactiveUI, you can use this.WhenAnyValue(x => x.PropName) to do exactly what you want.
I stumbled across this same problem recently, I ended up using PropertyChangeListener, which will emit an object when a property is changed, see the following:
Update Listener:
public class GameUpdateListener {
public static Observable<Object> changed(Game game) {
final BehaviorSubject<Object> subject = BehaviorSubject.create((Object)game);
game.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
subject.onNext( (Object)propertyChangeEvent.getNewValue());
}
});
return subject;
}
}
Some custom object:
public class Game {
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
...
public setSomeField(String field){
this.field = field;
pcs.firePropertyChange("field", this.field, field);
}
public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
pcs.addPropertyChangeListener(propertyChangeListener);
}
...
}
Observe:
Game game = new Game();
GameUpdateListener listener = new GameUpdateListener();
final Observable<Object> gameObserver = listener.changed(game);
gameObserver.subscribe(new Action1<Object>() {
#Override
public void call(Object o) {
Log.e(TAG, "Object Changed");
}
});
game.setSomeField("New value");
This will work fine as long as you don't need to instantiate your object again. Perhaps a solution to this is to create a local setter method and emit a change there.
Since your question title contains "or Rx.NET", here is my suggestion (I dunno bout RxJava, you may find something similar).
You probably will have to leverage some sort of mechanism in the setter. The standard way in .NET is by using the INotifyPropertyChanged interface.
Then by firing the events, you can create an IObservable<T> from this stream by using
Observable.FromEvent<TEvent, TArgs>()
You can find a really good example of what you want to do (.NET) here.
(credits to Rob Foncesa-Ensor)
I think what you are after is a Subject<T>. It implements IObserver<T>, so you can call OnNext(T) to fire a new value, as well as IObservable<T>, which you can expose it as publicly so it can be subscribed to.
If you need it to fire the latest value to new subscribers, you can use a ReplaySubject<T> with a buffer size of 1.
Here's a basic implementation:
public class SomeService
{
private Subject<int> values = new Subject<int>();
public IObservable<T> Values
{
get
{
// AsObservable prevents it from being cast back to Subject
return values.AsObservable();
}
}
// Private; called by some internal mechanism
private void SetValue(int newValue)
{
newValue.OnNext(newValue);
}
}
I'm a new to MassTransit and one thing I don't understand is this:
How do you create a bus between multiple .net ServiceBuses?
Take this code:
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.Register(AllTypes.FromThisAssembly().BasedOn<IConsumer>());
Console.WriteLine("Starting Buses!");
var bus1 = ServiceBusFactory.New(sbc =>
{
sbc.UseMsmq();
sbc.UseMulticastSubscriptionClient();
sbc.ReceiveFrom("msmq://localhost/bus1");
sbc.Subscribe(s => s.LoadFrom(container));
});
var bus2 = ServiceBusFactory.New(sbc =>
{
sbc.UseMsmq();
sbc.UseMulticastSubscriptionClient();
sbc.ReceiveFrom("msmq://localhost/bus2");
sbc.Subscribe(s => s.LoadFrom(container));
});
bus1.Publish(new TestMsg() { Name = "Hello Matt!" });
Console.WriteLine("Sent Message");
Console.ReadLine();
}
}
public class TestMsg
{
public string Name { get; set; }
}
public class TestMsgConsumer : Consumes<TestMsg>.All, IBusService
{
private IServiceBus bus;
public void Consume(TestMsg message)
{
Console.WriteLine("Got message on " + this.Context().Endpoint.Address);
}
public void Dispose()
{
if (bus != null)
bus.Dispose();
}
public void Start(IServiceBus bus)
{
this.bus = bus;
}
public void Stop()
{
}
}
I would expect the "Got message on ..." to show up twice, since I have two buses. However, I only get one. Obviously there is some step that ties these two Bus instances to the same logical bus I'm not understanding what that is. I can't point them at the same queue name since, again, only one would get the message.
Thanks!
EDIT/SOLUTION:
I got some help from the MT Google Groups and they got me straightened away quickly... this wasn't working as expected because I didn't have the multicast bits of MSMQ installed. Got those installed and it worked as expected.
See the original post for the answer, but it basically came down to not having the Multicast bits of MSMQ installed. Put those in and all works as expected.
I want to build a simple idea plugin, which will detect the changes of a kind of file, then convert them to another format.
Current, I use such code to do this:
VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() {
#Override
public void contentsChanged(VirtualFileEvent event) {
// do something
}
});
It works, but not efficient.
I found this article says:
The most efficient way to listen to VFS events is to implement the BulkFileListener interface and to subscribe with it to the VirtualFileManager.VFS_CHANGES topic.
But I can't find any example to implement it. How to do that?
I guess you'll have found the answer by now, but for others it seems to work like this
public class A implements ApplicationComponent, BulkFileListener {
private final MessageBusConnection connection;
public A() {
connection = ApplicationManager.getApplication().getMessageBus().connect();
}
public void initComponent() {
connection.subscribe(VirtualFileManager.VFS_CHANGES, this);
}
public void disposeComponent() {
connection.disconnect();
}
public void before(List<? extends VFileEvent> events) {
// ...
}
public void after(List<? extends VFileEvent> events) {
// ...
}
...
}
I'm new to WP7 and coming from iPhone development. On iPhone I'm used to use NSNotificationCenter to notify my program of something. NSNotificationCenter is build-in the framework out of the box. Is there something similar in WP7? I stumbled uppon MVVM-Light Toolkit but I'm not sure how to use it correctly.
What I want to do:
Register to an Notification-Id and do something when Notification-Id is received
Send Notification with Notification-Id and a context (object to pass to observers)
Everyone who registers to the same Notification-Id will be notified
So something like: Registering
NotificationCenter.Default.register(receiver, notification-id, delegate);
Sending:
NotificationCenter.Default.send(notification-id, context);
Example for Registering:
NotificationCenter.Default.register(this, NotifyEnum.SayHello, m => Console.WriteLine("hello world with context: " + m.Context));
Sending ...
NotificationCenter.Default.send(NotifyEnum.SayHello, "stackoverflow context");
Here is how to do with the MVVM Light Toolkit:
Registering:
Messenger.Default.Register<string>(this, NotificationId, m => Console.WriteLine("hello world with context: " + m.Context));
Sending:
Messenger.Default.Send<string>("My message", NotificationId);
Here http://www.silverlightshow.net/items/Implementing-Push-Notifications-in-Windows-Phone-7.aspx you will find a great example on how to use push notification on windows phone 7.
I'm pretty sure that you archive the same result as NSNotificationCenter by creating a singleton which holds a list of observables that implements a specific interface based on your bussiness requirements, or call a lamba, or trigger an event, for each message sent by this singleton you will interate the list of observables and checking the message id, once you find one or more, you can call the interface method, or execute the lambda expression or trigger the event defined to digest the message contents.
Something like below:
public class NotificationCenter {
public static NotificationCenter Default = new NotificationCenter();
private List<KeyValuePair<string, INotifiable>> consumers;
private NotificationCenter () {
consumers = new List<INotifiable>();
}
public void Register(string id, INotifiable consumer) {
consumers.Add(new KeyValuePair(id, consumer));
}
public void Send(String id, object data) {
foreach(KeyValuePair consumer : consumers) {
if(consumer.Key == id)
consumer.Value.Notify(data);
}
}
}
public interface INotifiable {
void Notify(object data);
}
public class ConsumerPage : PhoneApplicationPage, INotifiable {
public ConsumerPage() {
NotificationCenter.Default.Register("event", this);
}
private Notify(object data) {
//do what you want
}
}
public class OtherPage : PhoneApplicationPage {
public OtherPage() {
NotificationCenter.Default.Send("event", "Hello!");
}
}