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"); } }
注1-我在这里使用了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
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");
}
}