引用されたブロックテキストは、を使用してはならない理由をかなり説明していますがSubject<T>、簡単にするために、オブザーバーとオブザーバブルの機能を組み合わせ、その間に(カプセル化するか拡張するかにかかわらず)ある種の状態を注入しています。
ここで問題が発生します。これらの責任は、個別に区別する必要があります。
つまり、あなたの特定のいえ、ケースでは、懸念事項を小さな部分に分割することをお勧めします。
まず、スレッドがホットで、常にハードウェアを監視して、通知を発生させるシグナルを探します。通常、これをどのように行いますか? イベント。それではまず始めましょう。
EventArgsイベントを発生させることを定義しましょう。
// The event args that has the information.
public class BaseFrameEventArgs : EventArgs
{
public BaseFrameEventArgs(IBaseFrame baseFrame)
{
// Validate parameters.
if (baseFrame == null) throw new ArgumentNullException("IBaseFrame");
// Set values.
BaseFrame = baseFrame;
}
// Poor man's immutability.
public IBaseFrame BaseFrame { get; private set; }
}
これで、イベントを発生させるクラスです。注、これは(あなたが常にハードウェアバッファを監視実行中のスレッドを持っているので)、静的クラス、またはあなたがオンデマンドに加入して呼んで何かできています。これは必要に応じて変更する必要があります。
public class BaseFrameMonitor
{
// You want to make this access thread safe
public event EventHandler<BaseFrameEventArgs> HardwareEvent;
public BaseFrameMonitor()
{
// Create/subscribe to your thread that
// drains hardware signals.
}
}
これで、イベントを公開するクラスができました。Observablesはイベントに適しています。そんなにので、イベントのストリームを変換するための最初のクラスのサポートがあることに(イベントの複数回の発射などのイベントストリームを考える)IObservable<T>あなたは、標準のイベントパターンに従っている場合を通じて、実装静的のFromEventPattern方法でObservableクラス。
イベントのソースとFromEventPatternメソッドを使用して、次のIObservable<EventPattern<BaseFrameEventArgs>>ように簡単に作成できます(EventPattern<TEventArgs>クラスは、.NETイベントに表示されるもの、特に、派生EventArgs元のインスタンスと送信者を表すオブジェクトを具体化します)。
// The event source.
// Or you might not need this if your class is static and exposes
// the event as a static event.
var source = new BaseFrameMonitor();
// Create the observable. It's going to be hot
// as the events are hot.
IObservable<EventPattern<BaseFrameEventArgs>> observable = Observable.
FromEventPattern<BaseFrameEventArgs>(
h => source.HardwareEvent += h,
h => source.HardwareEvent -= h);
もちろん、あなたがしたいIObservable<IBaseFrame>が、それは簡単です、使用してSelect拡張メソッドを上Observable(あなたのようなLINQでする、と私たちは使いやすい方法でこれまでのすべてをラップすることができます)投影を作成するクラス:
public IObservable<IBaseFrame> CreateHardwareObservable()
{
// The event source.
// Or you might not need this if your class is static and exposes
// the event as a static event.
var source = new BaseFrameMonitor();
// Create the observable. It's going to be hot
// as the events are hot.
IObservable<EventPattern<BaseFrameEventArgs>> observable = Observable.
FromEventPattern<BaseFrameEventArgs>(
h => source.HardwareEvent += h,
h => source.HardwareEvent -= h);
// Return the observable, but projected.
return observable.Select(i => i.EventArgs.BaseFrame);
}