C# 并行处理接收事件

C# 并行处理接收事件,c#,system.reactive,reactive-programming,C#,System.reactive,Reactive Programming,如果我说 void ChangeQuote(string symbol, double bid, double ask) { } string[] TechETF = {"AAPL", "MSFT"}; var quotesSubscription = quotesObservable.Where(quote => (TechETF.Contains(quote.Symbol))); quotesSubscription.Subscribe(quote => this.Chang

如果我说

void ChangeQuote(string symbol, double bid, double ask)
{
}

string[] TechETF = {"AAPL", "MSFT"};
var quotesSubscription = quotesObservable.Where(quote => (TechETF.Contains(quote.Symbol)));

quotesSubscription.Subscribe(quote => this.ChangeQuote(quote.Symbol, quote.Bid, quote.Ask));

如果底层事件是异步触发的,那么
subscribe()
中的代码是否也在自己的线程(线程池)上异步处理这些回调?或者此代码是否序列化(阻止)这些回调的处理?

Rx始终序列化调用。这是行为契约的一部分

这里有一个例子来说明这一点

从两个计时器开始:

var timers = new []
{
    new System.Timers.Timer()
    {
        Interval = 200.0,
        AutoReset = true,
        Enabled = true,
    },
    new System.Timers.Timer()
    {
        Interval = 250.0,
        AutoReset = true,
        Enabled = true,
    },
};
现在,从计时器构建两个可观察对象:

var observables = new []
{
    Observable.FromEventPattern
        <System.Timers.ElapsedEventHandler, System.Timers.ElapsedEventArgs>
        (h => timers[0].Elapsed += h, h => timers[0].Elapsed -= h),
    Observable.FromEventPattern
        <System.Timers.ElapsedEventHandler, System.Timers.ElapsedEventArgs>
        (h => timers[1].Elapsed += h, h => timers[1].Elapsed -= h),
};
最后订阅,看看会发生什么:

observable
    .Subscribe(ep =>
    {
        Console.WriteLine("Start: " + Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(2000);
        Console.WriteLine("End: " + Thread.CurrentThread.ManagedThreadId);
    });
我得到的结果是:

Start: 15
End: 15
Start: 11
End: 11
Start: 14
End: 14
Start: 10
End: 10
Start: 4
End: 4
Start: 13
End: 13
Start: 12
End: 12
Start: 3
End: 3

因此,即使我的计时器彼此异步触发,Rx也确保单个订阅始终以串行方式处理每个值,即使它们位于不同的线程上。

如果您有两个用于相同可观察对象的OnNext处理程序并行运行,您不能再保证可观察对象提供的值是按照它们产生的顺序处理的。正如谜一样,这是Rx合同的一部分。因此,正如您在Enigmativity的示例中所看到的,Rx序列化了通知

将ObserveOn与Threadpool或NewThread调度程序一起使用并不意味着每个通知都可以并行运行。这意味着通知处理代码可以在不同于通知生产者的上下文中串联运行


如果您确实希望并行处理通知,并接受由此产生的竞争条件后果,那么您始终可以在通知处理程序中生成新的线程池任务或类似任务。通常这不是您真正想要做的。

Rx总是序列化调用。这是行为契约的一部分。也许是这样,但我的理解是,ObserveOn和SubscribeOn是内部分离的观察对象,它们可以在多个线程上运行。@Ivan-我不知道你所说的“内部分离的观察对象”是什么意思?所有的
ObserveOn
SubscribeOn
都是指定使用哪个调度程序-它们不会更改可观察订阅的序列性质。
Start: 15
End: 15
Start: 11
End: 11
Start: 14
End: 14
Start: 10
End: 10
Start: 4
End: 4
Start: 13
End: 13
Start: 12
End: 12
Start: 3
End: 3