你好,我试图理解为什么OnError
不会每次都被调用Observer
的原因。
尝试调试在OnError
实现中调用的IOBservable
时,调试器会通过。
可观察的实施方式
public class Reactive:IStorage,IObservable<SquareResult>
{
private object @lock = new object();
private List<IObserver<SquareResult>> observers = new List<IObserver<SquareResult>>();
public static Reactive Create()
{
return new Reactive();
}
public void Enqueue(SquareResult square)
{
lock (@lock)
{
foreach (var item in observers)
{
if (square.Result < 0)
{
item.OnError(new InvalidSquareException());
}
else
item.OnNext(square);
}
}
}
public void EndStoring()
{
this.observers.ForEach(obs => obs.OnCompleted());
}
public IDisposable Subscribe(IObserver<SquareResult> observer)
{
if (!this.observers.Contains(observer))
{
this.observers.Add(observer);
}
return new Unsubscriber(observer, this.observers);
}
public class Unsubscriber : IDisposable
{
private List<IObserver<SquareResult>> observers;
private IObserver<SquareResult> observer;
public Unsubscriber(IObserver<SquareResult>obs,List<IObserver<SquareResult>>observers)
{
this.observer = obs;
this.observers = observers;
}
public void Dispose()
{
if (this.observer == null)
{
return;
}
this.observers.Remove(this.observer);
}
}
}
生产者调用的唯一方法是Enqueue
。
然后我们有一个服务,其中consumer
从IObservable
提取数据并通过套接字发送数据:
消费者
class ProgressService
{
private IStorage observable;
public ProgressService(IStorage storage)
{
this.observable = storage;
}
public async Task NotifyAsync(WebSocket socket)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(1024);
CancellationTokenSource cancelSignal = new CancellationTokenSource();
this.observable.Subscribe(async (next) =>
{
try
{
ReadOnlyMemory<byte> data = next.Encode();
await socket.SendAsync(data, WebSocketMessageType.Text, true, CancellationToken.None);
}
catch (Exception)
{
if (socket.State == WebSocketState.Open)
{
await socket.CloseAsync(WebSocketCloseStatus.InternalServerError, "Threw on data receive", CancellationToken.None);
}
return;
}
}, async(ex) =>
{
//!! this delegate does not get called everytime the observable calls OnError(exception)
await socket.SendAsync($"Exception :{ex.Message}".Encode().ToArray(), WebSocketMessageType.Text, true, CancellationToken.None);
}, async () =>
{
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Finished test", CancellationToken.None);
}, cancelSignal.Token);
await socket.ReceiveAsync(buffer, CancellationToken.None);
cancelSignal.Cancel();
}
}
所以基本上发生的是,如果我从某个地方myobservable.OnError(new exception())
进行了两次调用,consumer
的回调仅被调用了一次,而我不明白为什么。
示例:
observable.OnError(new Exception());
observable.OnError(new Exception());
Observer.OnError导入
public void OnError(Exception ex)
{
Console.WriteLine(ex.Message);
}
我的代码中的上述示例仅会打印一次异常消息。
答案 0 :(得分:2)
'Observable contract'允许0或更多个flush
通知,随后是一个OnNext
或一个OnCompleted
通知,它们终止了可观察的状态。一旦观察对象终止(由您的情况中的第一个OnError
终止),将不再发出通知,这意味着不再调用任何委托。