هل يجب أن أستخدم القائمة أو ببساطة إجراء لتتبع مشتركي iobservable؟
-
25-09-2019 - |
سؤال
أنا أقوم بتنفيذ IObservable<T>
واجهة على بعض الفصول. انا إستعملت العاكس لمعرفة كيف يتم ذلك عادة في RX. فيما يتعلق بكيفية تتبع الملاحظة لمشتركيها وإعلامهم عبر OnNext
الطريقة ، لقد تعثرت على رمز مشابه لهذا:
private List<Observer<T>> observers;
// subscribe a new observer:
public IDisposable Subscribe(IObserver<T> observer)
{
observers.Add(observer);
...
}
// trigger all observers' OnNext method:
...
foreach (IObserver<T> observer in observers)
{
observer.OnNext(value);
}
نظرًا لأن جميع المندوبين متعددون ، لا يمكن تبسيط هذا إلى:
Action<T> observers;
// subscribe observer:
public IDisposable Subscribe(IObserver<T> observer)
{
observers += observer.OnNext;
...
}
// trigger observers' OnNext:
...
observers(value);
أم أن هناك مزايا محددة للنهج الأول (الأداء ، قضايا الخيوط/التزامن ، ...)؟
المحلول
بشكل عام ، يمنحك استدعاء المندوبين بشكل فردي مزيدًا من السيطرة على السلوك:
- إذا قام أحد المندوبين برفع استثناء ، فيمكنك الاستمرار في الاتصال بالآخرين ، على سبيل المثال ، أو إزالة مندوب الخطأ من قائمتك.
- إذا كنت ترغب في الاتصال بالمندوبين بالتوازي ، فهذا أمر سهل حقًا.
- إذا كنت بحاجة إلى الاتصال بهم بترتيب معين ، فيمكنك بسهولة ضمان الترتيب الصحيح (لست متأكدًا من تحديد ترتيب مكالمات البث المتعدد).
نصائح أخرى
عادة لا تنفذ IObservable<T>
نفسك ، يمكنك العودة IObservable<T>
من طريقة باستخدام إحدى طرق التوليد (مثل Observable.Create
).
ومع ذلك ، إذا كنت ستنفذ الواجهة بنفسك ، فيجب عليك لفه داخليًا Subject<T>
التي ستتعامل مع جميع مشكلات التزامن بالنسبة لك:
public class CustomObservable<T> : IObservable<T>
{
private Subject<T> subject = new Subject<T>();
public IDisposable Subscribe(IObserver<T> observer)
{
return subject.Subscribe(observer);
}
private void EmitValue(T value)
{
subject.OnNext(value);
}
}
NB: إذا قررت الالتزام بالمندوب (لأي سبب من الأسباب) ، تأكد على الأقل من إلغاء الاشتراك في الخاص بك IDisposable
قيمة الإرجاع:
observers += observer.OnNext;
return Disposable.Create(() => observers -= observer.OnNext);