可观察的<string>更新事件?</string>

时间:2010-10-11 18:10:05

标签: c# .net linq system.reactive

我只是想在字符串变量上做一个简单的事件处理程序,这样如果字符串发生变化,它就会执行一个Console.WriteLine(使用来自MS(Rx)的新Reactive库)

我遇到的问题是,当我实例化类时会显示第一位(“RandomGuid:Mine?”),但之后,我之后改变的东西都没有向控制台吐出任何东西。

我从MS网站上浏览了HOL,但直接从定义Observable到文本框中的读取值,当我想要做的就是观察字符串是否被更改。

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 => m.s = Observable.Return<string>("Mine"));
            minahs.ForEach(m => m.s = Observable.Return<string>("Whee"));
            minahs.ForEach(m => m.s = 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;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:4)

当您在m.s中分配给ForEach时,您没有使用新值更新现有的observable(您已订阅),而是创建新的observable,这是{{ 1}}。下面的代码符合我的预期:

Observable.Return

我没有使用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 => m.s.OnNext("Mine")); minahs.ForEach(m => m.s.OnNext("Whee")); minahs.ForEach(m => m.s.OnNext("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; } } } } ,而是使用Observable.Return<T>(),它既是观察者,也是可观察的序列。它使用它观察到的每个值更新所有订阅。因此,当在主题上调用Subject时,它将转发给所有订阅。

如果您需要初始值(OnNext),可以在Mine?构造函数的末尾添加s.OnNext("Mine?");

答案 1 :(得分:0)

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 => m.s.OnCompleted());

            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;
            }
        }
    }
}

这是我最终在马库斯的帮助下做的事情。更多地使用并行性。有趣的是,如果我从.ForAll(... RepeatWord = s)的末尾删除.Wait(),它只会执行序列中的最后一个单词。我猜这是封闭的事情,但我并不过分关注它。