.NET- র IObserver <T> একাধিক IObservables সাবস্ক্রাইব করার উদ্দেশ্যে করা হয়েছিল?


9

আছে IObservable এবং IObserver .NET (এছাড়াও মধ্যে ইন্টারফেসগুলি এখানে এবং এখানে )। মজার বিষয় হল, আইওবসভারের কংক্রিট বাস্তবায়ন আইওজার্ভেবলের প্রত্যক্ষ রেফারেন্স ধারণ করে না। এটি কারা সাবস্ক্রাইব হয়েছে তা জানে না। এটি কেবল সাবস্ক্রাইবকেই প্রার্থনা করতে পারে। "সাবস্ক্রাইব করতে দয়া করে পিনটি টানুন।"

সম্পাদনা: সদস্যতা বাতিল করে IDisposable। আমি মনে করি, শ্রোতাদের বিলম্বিত সমস্যা রোধ করতে এই স্কিমটি নিযুক্ত করা হয়েছিল ।

যদিও দুটি বিষয় আমার কাছে সম্পূর্ণ পরিষ্কার নয়।

  1. অভ্যন্তরীণ সাবস্ক্রাইবার শ্রেণি সাবস্ক্রাইব এবং ভুলে যাওয়া আচরণ সরবরাহ করে? কে (এবং ঠিক কখন) IDisposable.Dispose()আনসস্ক্রাইবারকে ফোন করে? আবর্জনা সংগ্রহকারী (জিসি) নির্বিচারবাদী নয়।
    [অস্বীকৃতি: সামগ্রিকভাবে, আমি সি # এর চেয়ে সি এবং সি ++ এর সাথে বেশি সময় ব্যয় করেছি]]
  2. যদি আমি একটি পর্যবেক্ষক কে একটি পর্যবেক্ষণযোগ্য এল 1 তে সাবস্ক্রাইব করতে চাই এবং পর্যবেক্ষক ইতিমধ্যে অন্য কিছু পর্যবেক্ষণযোগ্য এল 2 এর সদস্যতা পেয়েছি তবে কী হবে?

    K.Subscribe(L1);
    K.Subscribe(L2);
    K.Unsubscribe();
    L1.PublishObservation(1003);
    L2.PublishObservation(1004);
    

    আমি যখন এই পরীক্ষার কোডটি এমএসডিএন-এর উদাহরণের বিপরীতে চালিয়েছি, তখন পর্যবেক্ষক এল 1-তে সাবস্ক্রাইব রয়েছেন। এটি বাস্তব বিকাশে অদ্ভুত হবে। সম্ভবত এটির উন্নতি করার জন্য 3 টি উপায় রয়েছে:

    • যদি পর্যবেক্ষকের ইতিমধ্যে একটি সাবস্ক্রাইবার উদাহরণ রয়েছে (যেমন এটি ইতিমধ্যে সাবস্ক্রাইব হয়েছে), তবে এটি চুপচাপ কোনও নতুন সাবস্ক্রাইব করার আগে মূল সরবরাহকারীর কাছ থেকে সাবস্ক্রাইব করে। এই পদ্ধতির এই বিষয়টি গোপন করে যে এটি আর মূল সরবরাহকারীর সাথে সাবস্ক্রাইব করা হয়নি, যা পরে আশ্চর্য হয়ে যেতে পারে।
    • যদি পর্যবেক্ষকের কাছে ইতিমধ্যে একটি সাবস্ক্রাইবার উদাহরণ থাকে তবে তার ব্যতিক্রম ছুঁড়ে ফেলা হয়। একটি ভাল আচরণযুক্ত কলিং কোডটি পর্যবেক্ষককে স্পষ্টতই সাবস্ক্রাইব করতে হয়।
    • পর্যবেক্ষক একাধিক সরবরাহকারীর সাবস্ক্রাইব করে। এটি সবচেয়ে উদ্বেগজনক বিকল্প, তবে এটি কি আইওবসারেবল এবং আইওবসভারের সাথে প্রয়োগ করা যেতে পারে? দেখা যাক. পর্যবেক্ষকের পক্ষে সাবস্ক্রাইবার অবজেক্টের একটি তালিকা রাখা সম্ভব: প্রতিটি উত্সের জন্য একটি। দুর্ভাগ্যক্রমে, IObserver.OnComplete()যে সরবরাহকারী এটি প্রেরণ করেছেন তাদের কাছে কোনও রেফারেন্স সরবরাহ করে না। সুতরাং, একাধিক সরবরাহকারীর সাথে আইওজারবার বাস্তবায়ন কোনটি থেকে সাবস্ক্রাইব করতে হবে তা নির্ধারণ করতে সক্ষম হবে না।
  3. .NET- র IObserver একাধিক IObservables সাবস্ক্রাইব করার উদ্দেশ্যে ছিল?
    পর্যবেক্ষক প্যাটার্নের পাঠ্যপুস্তকের সংজ্ঞাটির জন্য কী একজন পর্যবেক্ষক একাধিক সরবরাহকারীর সাবস্ক্রাইব করতে সক্ষম হতে হবে? বা এটি alচ্ছিক এবং বাস্তবায়ন নির্ভর?

উত্তর:


5

দুটি ইন্টারফেস আসলে প্রতিক্রিয়াশীল এক্সটেনশনের অংশ (সংক্ষেপে আরএক্স), যখনই আপনি সেগুলি ব্যবহার করতে চান আপনার সেই লাইব্রেরিটি বেশ ব্যবহার করা উচিত।

ইন্টারফেসগুলি প্রযুক্তিগতভাবে এমএসক্রোলিতে হয়, কোনও আরএক্স অ্যাসেমব্লিতে নয়। আমি মনে করি এটি আন্তঃঅযোগাযোগ্যতা কমিয়ে আনার জন্য: এইভাবে, টিপিএল ডেটাফ্লোর মতো লাইব্রেরিগুলি আরএক্সকে উল্লেখ না করে সেই সদস্যদের সেই ইন্টারফেসগুলির সাথে কাজ করতে পারে ।

আপনি Rx এর ব্যবহার Subjectআপনার বাস্তবায়ন যেমন IObservable, Subscribeএকটি ফিরে আসবে IDisposableযে সদস্যতা রদ করা জন্য ব্যবহার করা যেতে পারে:

var observable = new Subject<int>();

var unsubscriber =
    observable.Subscribe(Observer.Create<int>(i => Console.WriteLine("1: {0}", i)));
observable.Subscribe(Observer.Create<int>(i => Console.WriteLine("2: {0}", i)));

unsubscriber.Dispose();

observable.OnNext(1003);
observable.OnNext(1004);

5

অফিসিয়াল আরএক্স ডিজাইন গাইডলাইনগুলিতে এবং আমার ওয়েবসাইট ইন্ট্রোটোআরএক্স.কম এ দৈর্ঘ্যের বেশ কয়েকটি বিষয় পরিষ্কার করার জন্য :

  • আপনার সদস্যতাগুলি পরিষ্কার করতে আপনি জিসির উপর নির্ভর করবেন না। এখানে বিস্তারিত কভার করা হয়েছে
  • কোন Unsubscribeপদ্ধতি নেই। আপনি একটি পর্যবেক্ষণযোগ্য ক্রম সাবস্ক্রাইব এবং একটি সাবস্ক্রিপশন দেওয়া হয় । তারপরে আপনি সেই সাবস্ক্রিপশনটি নিষ্পত্তি করতে পারেন এটি নির্দেশ করে যে আপনি আর নিজের কলব্যাকগুলি চালিত করতে চান না।
  • একটি পর্যবেক্ষণযোগ্য ক্রম একাধিকবার সম্পন্ন করা যাবে না (আরএক্স ডিজাইন নির্দেশিকাগুলির বিভাগ 4 দেখুন)।
  • একাধিক পর্যবেক্ষণযোগ্য ক্রম গ্রাস করার বিভিন্ন উপায় রয়েছে। এছাড়া যে সংক্রান্ত তথ্য একটি সম্পদ Reactivex.io এবং আবার IntroToRx করেন।

নির্দিষ্ট হতে এবং সরাসরি আসল প্রশ্নের উত্তর দেওয়ার জন্য, আপনার ব্যবহারটি আবার সামনে। আপনি একক পর্যবেক্ষকের মধ্যে অনেকগুলি পর্যবেক্ষণযোগ্য অনুক্রমকে ঠেলাবেন না। আপনি পর্যবেক্ষণযোগ্য ক্রমগুলি একটি একক পর্যবেক্ষণযোগ্য অনুক্রমের মধ্যে রচনা করেছেন। তারপরে আপনি সেই একক ক্রমের সাবস্ক্রাইব করুন।

পরিবর্তে

K.Subscribe(L1);
K.Subscribe(L2);
K.Unsubscribe();
L1.PublishObservation(1003);
L2.PublishObservation(1004);

যা কেবল ছদ্ম কোড এবং Rx এর নেট নেট প্রয়োগে কাজ করবে না, আপনার নিম্নলিখিতটি করা উচিত:

var source1 = new Subject<int>(); //was L1
var source2 = new Subject<int>(); //was L2

var subscription = source1
    .Merge(source2)
    .Subscribe(value=>Console.WriteLine("OnNext({0})", value));


source1.OnNext(1003);
source2.OnNext(1004);

subscription.Dispose();

এখন এটি প্রাথমিক প্রশ্নের সাথে পুরোপুরি ফিট করে না, তবে কী K.Unsubscribe()করা উচিত ছিল তা আমি জানি না (সব থেকে সদস্যতা, শেষ বা প্রথম সাবস্ক্রিপশন ?!)


আমি কি কেবল "ব্যবহার করে" ব্লকে সাবস্ক্রিপশন অবজেক্টটি এনক্যাস করতে পারি?
রবার্ট অসলারের

1
এই সিঙ্ক্রোনাস ক্ষেত্রে আপনি পারেন, তবে আরএক্স অ্যাসিঙ্ক্রোনাস বলে মনে করা হচ্ছে। অ্যাসিঙ্ক্রোনাস ক্ষেত্রে, আপনি সাধারণত usingব্লকটি ব্যবহার করতে পারবেন না । সাবস্ক্রিপশন স্টেটমেন্টের জন্য ব্যয়টি ভার্চুয়াল শূন্য হওয়া উচিত, সুতরাং আপনি ব্যবহারের ব্লকটি আরও কম করে নিবেন, সাবস্ক্রাইব করবেন, কোডটি বরং অর্থহীন করে ব্যবহারের ব্লকটি ছেড়ে দেবেন (এভাবে সাবস্ক্রাইব করুন)
লি ক্যাম্পবেল

3

তুমি ঠিক বলছো. উদাহরণটি একাধিক IObservables জন্য খারাপভাবে কাজ করে।

আমার ধারণা অনকম্পল () কোনও রেফারেন্স সরবরাহ করে না কারণ তারা চায় না যে IObservable এটিকে প্রায় রাখে। আমি যদি লিখছিলাম যে আমি সম্ভবত সাবস্ক্রাইব করে দ্বিতীয় পরামিতি হিসাবে কোনও শনাক্তকারীকে গ্রহণ করে একাধিক সাবস্ক্রিপশনকে সমর্থন করব, যা অনকমল্ট () কলটিতে ফিরে আসে। সুতরাং আপনি বলতে পারেন

K.Subscribe(L1,"L1")
K.Subscribe(L2,"L2")
K.Unsubscribe("L1")

এটি যেমন দাঁড়িয়েছে, এটি প্রদর্শিত হয়। নেট IObserver একাধিক পর্যবেক্ষকের জন্য উপযুক্ত নয়। তবে আমি মনে করি আপনার মূল অবজেক্ট (উদাহরণে অবস্থানের প্রতিবেদক) থাকতে পারে

public Dictionary<String,IObserver> Observers;

এবং এটি আপনাকে সমর্থন করতে সক্ষম করবে

K.Subscribe(L1,"L1")
K.Subscribe(L2,"L2")
K.Unsubscribe("L1")

যেমন.

আমি মনে করি মাইক্রোসফ্ট তর্ক করতে পারে যে তাদের জন্য ইন্টারফেসগুলিতে সরাসরি একাধিক আইওজার্ভ্যাসেবল সমর্থন করার প্রয়োজন নেই।


আমি আরও ভাবছিলাম যে পর্যবেক্ষণযোগ্য বাস্তবায়নে পর্যবেক্ষকদের একটি তালিকা থাকতে পারে। আমিও লক্ষ্য করেছি যে IObserver.OnComplete()কলটি কে এসেছে তা সনাক্ত করতে পারে না। যদি পর্যবেক্ষক একাধিক পর্যবেক্ষণযোগ্যতে সাবস্ক্রাইব হন তবে কারা সাবস্ক্রাইব করবেন তা জানেন না। Anticlimactic। আমি ভাবছি, .NET এর পর্যবেক্ষক নিদর্শনগুলির জন্য আরও ভাল ইন্টারফেস রয়েছে?
নিক আলেক্সেভ

আপনি যদি কোনও কিছুর রেফারেন্স পেতে চান তবে আপনার আসলে স্ট্রিং নয়, একটি রেফারেন্স ব্যবহার করা উচিত।
এসভিক

এই উত্তরটি আমাকে বাস্তব জীবনের ত্রুটি সহ সহায়তা করেছে। আমি Observable.Create()একটি পর্যবেক্ষণযোগ্য তৈরি করতে ব্যবহার করছি এবং এটি ব্যবহার করে বেশ কয়েকটি উত্স পর্যবেক্ষণযোগ্যকে শৃঙ্খলাবদ্ধ করছি Subscribe()। আমি অজান্তেই একটি কোড পথে একটি সম্পূর্ণ পর্যবেক্ষণযোগ্য পাস করেছি। অন্যান্য উত্সগুলি সম্পূর্ণ না হলেও এটি আমার সদ্য নির্মিত পর্যবেক্ষণযোগ্য সম্পন্ন করেছে। আমার যা করা দরকার তা কাজে লাগানোর জন্য আমাকে যুগ যুগ ধরে নিয়ে গেছে - স্যুইচ Observable.Empty()করুন Observable.Never()
ওলি

0

আমি জানি এই হল উপায় পার্টি দেরী, কিন্তু ...

ইন্টারফেসগুলি আমি Observable<T>এবং IObserver<T>হয় না Rx ... তারা কোর ধরনের অংশ ... কিন্তু Rx তাদের ব্যাপক ব্যবহার করে।

আপনি নিজের পছন্দমতো (বা কয়েকটি) পর্যবেক্ষক নিখরচায় থাকতে পারেন। আপনি যদি একাধিক পর্যবেক্ষককে অনুমান করেন, তবে OnNext()প্রতিটি পর্যবেক্ষণ করা ইভেন্টের জন্য উপযুক্ত পর্যবেক্ষকদের কাছে কল রুট করা পর্যবেক্ষকের দায়িত্ব । আপনার পরামর্শ অনুসারে পর্যবেক্ষণযোগ্যদের জন্য একটি তালিকা বা অভিধান প্রয়োজন হতে পারে।

কেবলমাত্র একজনকে অনুমতি দেওয়ার জন্য ভাল কেস রয়েছে - এবং অনেককে অনুমতি দেওয়ার জন্য ভাল কেস রয়েছে। উদাহরণস্বরূপ, একটি সিকিউআরএস / ইএস প্রয়োগকরণে, আপনি কমান্ড বাসে প্রতিটি কমান্ড টাইপ করে একক কমান্ড হ্যান্ডলার প্রয়োগ করতে পারেন, যখন আপনি ইভেন্ট স্টোরটিতে প্রদত্ত ইভেন্ট প্রকারের জন্য কয়েকটি রিড-সাইড ট্রান্সফর্মকে অবহিত করতে পারেন ।

অন্যান্য উত্তরে যেমন বলা আছে তেমন নেই Unsubscribe। আপনি যখন Subscribeনোংরা কাজটি করেন তখন আপনার দেওয়া জিনিসটিকে নিষ্পত্তি করা । পর্যবেক্ষক, বা এর এজেন্ট, টোকেন ধরে রাখার জন্য দায়বদ্ধ যতক্ষণ না এটি আর বিজ্ঞপ্তি না পেতে চায় । (প্রশ্ন 1)

সুতরাং, আপনার উদাহরণে:

K.Subscribe(L1);
K.Subscribe(L2);
K.Unsubscribe();
L1.PublishObservation(1003);
L2.PublishObservation(1004);

... এটি আরও ভালো হবে:

using ( var l1Token = K.Subscribe( L1 ) )
{
  using ( var l2Token = K.Subscribe( L2 );
  {
    L1.PublishObservation( 1003 );
    L2.PublishObservation( 1004 );
  } //--> effectively unsubscribing to L2 here

  L2.PublishObservation( 1005 );
}

... যেখানে কে 1003 এবং 1004 শুনবে কিন্তু 1005 নয়।

আমার কাছে এটি এখনও মজাদার দেখাচ্ছে কারণ নামমাত্র হিসাবে, সাবস্ক্রিপশনগুলি দীর্ঘকালীন জিনিস ... প্রায়শই প্রোগ্রামের সময়কালের জন্য। তারা সাধারণ। নেট ইভেন্টের ক্ষেত্রে এই ক্ষেত্রে আলাদা নয়।

আমি দেখেছি অনেক উদাহরণে, Disposeটোকেনটি পর্যবেক্ষকদের পর্যবেক্ষকের তালিকা থেকে পর্যবেক্ষককে সরাতে কাজ করে। আমি পছন্দ করি যে টোকেনটি এত বেশি জ্ঞান বহন করে না ... এবং তাই আমি আমার সাবস্ক্রিপশন টোকেনকে কেবলমাত্র একটি পাস-ইন ল্যাম্বদা কল করতে সাবস্ক্রাইব করেছি (সাবস্ক্রাইব-সময়ে বন্দী তথ্য সনাক্তকরণ সহ:

public class SubscriptionToken<T>: IDisposable
{
  private readonly Action unsubscribe;

  private SubscriptionToken( ) { }
  public SubscriptionToken( Action unsubscribe )
  {
    this.unsubscribe = unsubscribe;
  }

  public void Dispose( )
  {
    unsubscribe( );
  }
}

... এবং পর্যবেক্ষণযোগ্য সাবস্ক্রিপশন চলাকালীন সাবস্ক্রাইব আচরণটি ইনস্টল করতে পারে:

IDisposable Subscribe<T>( IObserver<T> observer )
{
  var subscriberId = Guid.NewGuid( );
  subscribers.Add( subscriberId, observer );

  return new SubscriptionToken<T>
  (
    ( ) =>
    subscribers.Remove( subscriberId );
  );
}

যদি আপনার পর্যবেক্ষক একাধিক পর্যবেক্ষণযোগ্যদের কাছ থেকে ইভেন্টগুলি ধরে রাখছেন তবে আপনি তা নিশ্চিত করতে চাইতে পারেন যে ইভেন্টগুলিতে তারা কোনও ধরণের পারস্পরিক সম্পর্কের তথ্য রয়েছে ... যেমন। নেট ইভেন্টগুলি এর সাথে করে sender। এটি গুরুত্বপূর্ণ কিনা তা আপনার উপর নির্ভর করে। আপনি সঠিকভাবে যুক্তি হিসাবে এটি বেকড না। (প্রশ্ন 3)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.