Reactive Extensions에는 기존 이벤트와 비동기 작업을 관찰 가능으로 바꾸기위한 많은 도우미 방법이 있지만 IObservable <T>을 처음부터 구현하는 방법은 무엇입니까?처음부터 IObservable <T> 구현하기
IEnumerable에는 구현하기가 매우 쉬운 lovely yield 키워드가 있습니다.
IObservable을 구현하는 적절한 방법은 무엇입니까 <T>?
스레드 안전성에 대해 걱정할 필요가 있습니까?
특정 동기화 컨텍스트에서 다시 호출되는 것에 대한 지원이 있다는 것을 알고 있지만 IObservable 인 것입니다. <T> 작성자가 걱정할 필요가 있거나 어떻게 든 내장되어 있습니까?
갱신 :
여기에 브라이언의 F 번호 솔루션의 내 C# 버전입니다
using System;
using System.Linq;
using Microsoft.FSharp.Collections;
namespace Jesperll
{
class Observable<T> : IObservable<T>, IDisposable where T : EventArgs
{
private FSharpMap<int, IObserver<T>> subscribers =
FSharpMap<int, IObserver<T>>.Empty;
private readonly object thisLock = new object();
private int key;
private bool isDisposed;
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing && !isDisposed)
{
OnCompleted();
isDisposed = true;
}
}
protected void OnNext(T value)
{
if (isDisposed)
{
throw new ObjectDisposedException("Observable<T>");
}
foreach (IObserver<T> observer in subscribers.Select(kv => kv.Value))
{
observer.OnNext(value);
}
}
protected void OnError(Exception exception)
{
if (isDisposed)
{
throw new ObjectDisposedException("Observable<T>");
}
if (exception == null)
{
throw new ArgumentNullException("exception");
}
foreach (IObserver<T> observer in subscribers.Select(kv => kv.Value))
{
observer.OnError(exception);
}
}
protected void OnCompleted()
{
if (isDisposed)
{
throw new ObjectDisposedException("Observable<T>");
}
foreach (IObserver<T> observer in subscribers.Select(kv => kv.Value))
{
observer.OnCompleted();
}
}
public IDisposable Subscribe(IObserver<T> observer)
{
if (observer == null)
{
throw new ArgumentNullException("observer");
}
lock (thisLock)
{
int k = key++;
subscribers = subscribers.Add(k, observer);
return new AnonymousDisposable(() =>
{
lock (thisLock)
{
subscribers = subscribers.Remove(k);
}
});
}
}
}
class AnonymousDisposable : IDisposable
{
Action dispose;
public AnonymousDisposable(Action dispose)
{
this.dispose = dispose;
}
public void Dispose()
{
dispose();
}
}
}
편집 : 폐기 두 번
Wes Dyer는 이제 Channel9에서 이러한 인터페이스에 대한 계약서에 관한 비디오를 제공합니다. – Benjol
(30 초 후 ... http://channel9.msdn.com/posts/J.Van.Gogh/Reactive-Extensions-API-in-depth-Contract/) – Benjol
쿨 - 그것을보아야합니다 :) –