Observed <string> updated events?

I'm just trying to make a simple event handler in a string variable, so if the string changes, it will execute Console.WriteLine (using the new react library from MS (Rx))

The problem that I have is that it will display the first bit when I create an instance of the class ("RandomGuid: Mine?"), But after that, none of the materials that I later mixed up did not spit on the console .

I went through the HOL from the MS website, but right from the definition of the Observable value in the read values ​​from the text field, when all I want to do is see if the string has been changed.

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MynahBirds { class Program { static void Main(string[] args) { List<Minah> minahs = new List<Minah>(); for (int i = 0; i < 10; i++) { minahs.Add(new Minah()); } foreach (var item in minahs) { item.peers = minahs; } minahs.ForEach(m => ms = Observable.Return<string>("Mine")); minahs.ForEach(m => ms = Observable.Return<string>("Whee")); minahs.ForEach(m => ms = Observable.Return<string>("Argh")); Console.ReadLine(); } } class Minah { Guid Id; public List<Minah> peers; IDisposable subscription; public IObservable<string> s = Observable.Return<string>("Mine?"); public Minah() { try { this.Id = Guid.NewGuid(); subscription = s.Subscribe((string a) => { Console.WriteLine("{0} : {1}", this.Id, a); }, (Exception ex) => { Console.WriteLine("Error {0} hit", ex.ToString()); }, () => { }); } catch (Exception ex) { Console.WriteLine(ex.ToString()); Console.ReadLine(); throw; } } } } 
+4
source share
2 answers

When you assign ms to ForEach , you are not updating the existing observable (which you signed) with the new value, instead you create new observables, which is what Observable.Return does. The following code does what I think you expect:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MynahBirds { class Program { static void Main(string[] args) { List<Minah> minahs = new List<Minah>(); for (int i = 0; i < 10; i++) { minahs.Add(new Minah()); } foreach (var item in minahs) { item.peers = minahs; } minahs.ForEach(m => msOnNext("Mine")); minahs.ForEach(m => msOnNext("Whee")); minahs.ForEach(m => msOnNext("Argh")); Console.ReadLine(); } } class Minah { Guid Id; public List<Minah> peers; IDisposable subscription; public ISubject<string> s = new Subject<string>(); public Minah() { try { this.Id = Guid.NewGuid(); subscription = s.Subscribe((string a) => { Console.WriteLine("{0} : {1}", this.Id, a); }, (Exception ex) => { Console.WriteLine("Error {0} hit", ex.ToString()); }, () => { }); } catch (Exception ex) { Console.WriteLine(ex.ToString()); Console.ReadLine(); throw; } } } } 

Instead of using Observable.Return<T>() here I use Subject , which is both an observer and an observable sequence. It updates all its subscriptions with every value that it observes. Therefore, when an OnNext call OnNext called on an object, it is forwarded to all subscriptions.

If you need an initial value ( Mine? ), You can add s.OnNext("Mine?"); to the end of the Minah constructor.

+4
source
 using System; using System.Collections.Generic; using System.Threading; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; using System.Collections.Concurrent; namespace MynahBirds { class Program { static void Main(string[] args) { ThreadPool.SetMaxThreads(100, 100); ConcurrentBag<Minah> minahs = new ConcurrentBag<Minah>(); Stopwatch ti = new Stopwatch(); ti.Start(); Task.Factory.StartNew(() => { for (int i = 1; i < 2501; i++) { minahs.Add(new Minah(i)); }; }); Task.Factory.StartNew(() => { for (int i = 1; i < 2501; i++) { minahs.Add(new Minah(i)); }; }); Task.Factory.StartNew(() => { for (int i = 1; i < 2501; i++) { minahs.Add(new Minah(i)); }; }); Task.Factory.StartNew(() => { for (int i = 1; i < 2501; i++) { minahs.Add(new Minah(i)); }; }); Task.WaitAll(); string[] alpha = { "Alpha", "Bravo", "Charlie", "Delta", "Eagle", "Foxtrot", "Gulf", "Hotel" }; foreach (string s in alpha) { Console.WriteLine(s); Task.Factory.StartNew(() => minahs.AsParallel().ForAll(m => m.RepeatWord = s)).Wait(); } minahs.AsParallel().ForAll(m => msOnCompleted()); ti.Stop(); Console.WriteLine("{1} birds : {0} seconds", ti.Elapsed.TotalSeconds, minahs.Count); Console.ReadLine(); } } class Minah { Guid Id; IDisposable subscription; public ISubject<string> s = new Subject<string>(); private string _RepeatWord; public string RepeatWord { get { return _RepeatWord; } set { this.s.OnNext(value); _RepeatWord = value; } } public Minah(int i) { try { this.Id = Guid.NewGuid(); subscription = s.Subscribe((string a) => { Console.WriteLine("{0} : {1}", i, a); }, (Exception ex) => { Console.WriteLine("Error {0} hit", ex.ToString()); }, () => { /* Console.WriteLine("{0} : Completed", this.Id); */ }); } catch (Exception ex) { Console.WriteLine(ex.ToString()); Console.ReadLine(); throw; } } } } 

Here is what I did with the help of Marcus. Play more with parallelism. Interestingly, if I remove .Wait () from the end of .ForAll (... RepeatWord = s), it will only do the last word in the sequence. I guess this is a close, but I'm not too worried about that.

0
source

All Articles