C# } }); var task2=Task.Factory.StartNew(()=> { 对于(int i=0;i具有较少的迭代次数,因此我认为它可能首先运行。您可能想考虑用主题< /代码>替换可发布可观察的< /代码>。我试图从可观察工厂中找到类似PublishObservable的东西,但我不知道它的存在或它是独立的。 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var loginInitial = new LoginInitial(); var loginCheckList = new LoginCheckList(); var result1 = from x in loginInitial.Status from y in loginCheckList.Status where x == "Test" && y == "West" select new { x, y }; result1.Subscribe(x => MessageBox.Show(x.x + "-" + x.y)); var result2 = from x in loginInitial.Status where x == "Test" select x; result2.Subscribe(x => MessageBox.Show(x)); var result3 = from x in loginCheckList.Status where x == "West" select x; result3.Subscribe(x => MessageBox.Show(x)); var task1 = Task.Factory.StartNew(() => { for (int i = 0; i < 10000000; i++) { if (i == 9000000) loginInitial.Status.Publish("9000000"); if (i == 9000001) loginInitial.Status.Publish("Test"); } }); var task2 = Task.Factory.StartNew(() => { for (int i = 0; i < 1000000; i++) { if (i == 800000) loginInitial.Status.Publish("800000"); if (i == 800001) loginCheckList.Status.Publish("West"); } }); Task.WaitAll(task1, task2); MessageBox.Show("Done"); } } public class LoginInitial { public PublishObservable<string> Status = new PublishObservable<string>(); } public class LoginCheckList { public PublishObservable<string> Status = new PublishObservable<string>(); } public class PublishObservable<T> : IObservable<T> { private IList<IObserver<T>> _observers = new List<IObserver<T>>(); public void Publish(T value) { lock (_observers) { foreach (var observer in _observers) { observer.OnNext(value); } } } public void Complete() { lock (_observers) { foreach (var observer in _observers) { observer.OnCompleted(); } } } public IDisposable Subscribe(IObserver<T> observer) { lock (_observers) { _observers.Add(observer); } return null; } } var result1 = from x in loginInitial.Status from y in loginCheckList.Status where x == "Test" && y == "West" select new { x, y }; public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var loginInitial = new Subject<String>(); var loginCheckList = new Subject<String>(); var result1 = loginInitial.CombineLatest(loginCheckList, (x, y) => new Tuple<string, string>(x, y)) .Where(latest => latest.Item1 == "Test" && latest.Item2 == "West") .Select(latest => string.Format("{0} - {1}", latest.Item1, latest.Item2)); var result2 = from x in loginInitial where x == "Test" select x; var result3 = from x in loginCheckList where x == "West" select x; Observable.Merge(result1, result2, result3) .Subscribe(Console.WriteLine); var task1 = Task.Factory.StartNew(() => { for (int i = 0; i < 10000000; i++) { if (i == 9000000) loginInitial.OnNext("9000000"); if (i == 9000001) loginInitial.OnNext("Test"); } }); var task2 = Task.Factory.StartNew(() => { for (int i = 0; i < 1000000; i++) { if (i == 800000) loginInitial.OnNext("800000"); if (i == 800001) loginCheckList.OnNext("West"); } }); Task.WaitAll(task1, task2); Console.WriteLine("Done"); } }

C# } }); var task2=Task.Factory.StartNew(()=> { 对于(int i=0;i具有较少的迭代次数,因此我认为它可能首先运行。您可能想考虑用主题< /代码>替换可发布可观察的< /代码>。我试图从可观察工厂中找到类似PublishObservable的东西,但我不知道它的存在或它是独立的。 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var loginInitial = new LoginInitial(); var loginCheckList = new LoginCheckList(); var result1 = from x in loginInitial.Status from y in loginCheckList.Status where x == "Test" && y == "West" select new { x, y }; result1.Subscribe(x => MessageBox.Show(x.x + "-" + x.y)); var result2 = from x in loginInitial.Status where x == "Test" select x; result2.Subscribe(x => MessageBox.Show(x)); var result3 = from x in loginCheckList.Status where x == "West" select x; result3.Subscribe(x => MessageBox.Show(x)); var task1 = Task.Factory.StartNew(() => { for (int i = 0; i < 10000000; i++) { if (i == 9000000) loginInitial.Status.Publish("9000000"); if (i == 9000001) loginInitial.Status.Publish("Test"); } }); var task2 = Task.Factory.StartNew(() => { for (int i = 0; i < 1000000; i++) { if (i == 800000) loginInitial.Status.Publish("800000"); if (i == 800001) loginCheckList.Status.Publish("West"); } }); Task.WaitAll(task1, task2); MessageBox.Show("Done"); } } public class LoginInitial { public PublishObservable<string> Status = new PublishObservable<string>(); } public class LoginCheckList { public PublishObservable<string> Status = new PublishObservable<string>(); } public class PublishObservable<T> : IObservable<T> { private IList<IObserver<T>> _observers = new List<IObserver<T>>(); public void Publish(T value) { lock (_observers) { foreach (var observer in _observers) { observer.OnNext(value); } } } public void Complete() { lock (_observers) { foreach (var observer in _observers) { observer.OnCompleted(); } } } public IDisposable Subscribe(IObserver<T> observer) { lock (_observers) { _observers.Add(observer); } return null; } } var result1 = from x in loginInitial.Status from y in loginCheckList.Status where x == "Test" && y == "West" select new { x, y }; public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var loginInitial = new Subject<String>(); var loginCheckList = new Subject<String>(); var result1 = loginInitial.CombineLatest(loginCheckList, (x, y) => new Tuple<string, string>(x, y)) .Where(latest => latest.Item1 == "Test" && latest.Item2 == "West") .Select(latest => string.Format("{0} - {1}", latest.Item1, latest.Item2)); var result2 = from x in loginInitial where x == "Test" select x; var result3 = from x in loginCheckList where x == "West" select x; Observable.Merge(result1, result2, result3) .Subscribe(Console.WriteLine); var task1 = Task.Factory.StartNew(() => { for (int i = 0; i < 10000000; i++) { if (i == 9000000) loginInitial.OnNext("9000000"); if (i == 9000001) loginInitial.OnNext("Test"); } }); var task2 = Task.Factory.StartNew(() => { for (int i = 0; i < 1000000; i++) { if (i == 800000) loginInitial.OnNext("800000"); if (i == 800001) loginCheckList.OnNext("West"); } }); Task.WaitAll(task1, task2); Console.WriteLine("Done"); } },c#,.net,asynchronous,system.reactive,C#,.net,Asynchronous,System.reactive,注1-我在这里使用了combinelatetest,但根据您需要的行为,您也可以轻松地将其更改为使用Zip。查看RxAs页面上的大理石图,以了解和更好地了解它们的行为 注2-我可能会更改result2和result3以使用扩展方法语法,这样就不会在一个方法中混合使用多种方法。它的方式没有问题,但我更喜欢在可能的情况下使用一种语法的一致性。@vdh\u ant:原则上,是的-这就是为什么您需要Zip或combinelateest而不是中的嵌套(又称SelectMany)。在您提供的示例中, Log

注1-我在这里使用了
combinelatetest
,但根据您需要的行为,您也可以轻松地将其更改为使用
Zip
。查看RxAs页面上的大理石图,以了解和更好地了解它们的行为


注2-我可能会更改result2和result3以使用扩展方法语法,这样就不会在一个方法中混合使用多种方法。它的方式没有问题,但我更喜欢在可能的情况下使用一种语法的一致性。

@vdh\u ant:原则上,是的-这就是为什么您需要
Zip
combinelateest
而不是
中的嵌套
(又称
SelectMany
)。在您提供的示例中,<代码> Login检查列表< /代码>具有较少的迭代次数,因此我认为它可能首先运行。您可能想考虑用<代码>主题< /代码>替换<代码>可发布可观察的< /代码>。我试图从可观察工厂中找到类似PublishObservable的东西,但我不知道它的存在或它是独立的。
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent(); 

        var loginInitial = new LoginInitial();
        var loginCheckList = new LoginCheckList();



        var result1 = from x in loginInitial.Status
                    from y in loginCheckList.Status
                    where x == "Test" && y == "West"
                    select new { x, y };

        result1.Subscribe(x => MessageBox.Show(x.x + "-" + x.y));

        var result2 = from x in loginInitial.Status
                      where x == "Test"
                      select x;

        result2.Subscribe(x => MessageBox.Show(x));

        var result3 = from x in loginCheckList.Status
                      where x == "West"
                      select x;

        result3.Subscribe(x => MessageBox.Show(x));

        var task1 = Task.Factory.StartNew(() =>
                                  {
                                      for (int i = 0; i < 10000000; i++)
                                      {
                                          if (i == 9000000)
                                              loginInitial.Status.Publish("9000000");
                                          if (i == 9000001)
                                              loginInitial.Status.Publish("Test");
                                      }
                                  });

        var task2 = Task.Factory.StartNew(() =>
                                  {
                                        for (int i = 0; i < 1000000; i++)
                                        {
                                            if (i == 800000)
                                                loginInitial.Status.Publish("800000");
                                            if (i == 800001)
                                                loginCheckList.Status.Publish("West");
                                        }
                                  });
        Task.WaitAll(task1, task2);

        MessageBox.Show("Done");
    }
}

public class LoginInitial
{
    public PublishObservable<string> Status = new PublishObservable<string>(); 
}

public class LoginCheckList
{
    public PublishObservable<string> Status = new PublishObservable<string>();
}

public class PublishObservable<T> : IObservable<T>
{
    private IList<IObserver<T>> _observers = new List<IObserver<T>>();

    public void Publish(T value)
    {
        lock (_observers)
        {
            foreach (var observer in _observers)
            {
                observer.OnNext(value);
            }
        }
    }

    public void Complete()
    {
        lock (_observers)
        {
            foreach (var observer in _observers)
            {
                observer.OnCompleted();
            }
        }
    }

    public IDisposable Subscribe(IObserver<T> observer)
    {
        lock (_observers)
        {
            _observers.Add(observer);
        }
        return null;
    }
}
var result1 = 
  from x in loginInitial.Status
  from y in loginCheckList.Status
  where x == "Test" && y == "West"
  select new { x, y }; 
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent(); 

        var loginInitial = new Subject<String>();
        var loginCheckList = new Subject<String>();

        var result1 = loginInitial.CombineLatest(loginCheckList, 
                (x, y) => new Tuple<string, string>(x, y))
            .Where(latest => latest.Item1 == "Test" && latest.Item2 == "West")
            .Select(latest => string.Format("{0} - {1}", latest.Item1, latest.Item2));

        var result2 = from x in loginInitial
                        where x == "Test"
                        select x;

        var result3 = from x in loginCheckList
                        where x == "West"
                        select x;

        Observable.Merge(result1, result2, result3)
            .Subscribe(Console.WriteLine);

        var task1 = Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 10000000; i++)
            {
                if (i == 9000000)
                    loginInitial.OnNext("9000000");
                if (i == 9000001)
                    loginInitial.OnNext("Test");
            }
        });

        var task2 = Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 1000000; i++)
            {
                if (i == 800000)
                    loginInitial.OnNext("800000");
                if (i == 800001)
                    loginCheckList.OnNext("West");
            }
        });

        Task.WaitAll(task1, task2);

        Console.WriteLine("Done");
    }
}