1
\$\begingroup\$

As a result of my previous post, I have implemented / refactored my code and have started making successful use of my class. However I have come across a couple of new questions:

  1. The observer must call PopObjects() to consume the data in the vector. PopObjects() returns a bool so I don not have to check the vector count. However, this allows me put the call in a while loop which could never break if the data producer(s) are producing faster than I can consume. I think this concern out of the scope of this class or can it be solved easily within?
  2. I like to assign values to my class members (simulating c++ initializer lists). Is this overkill?
  3. I noticed I cannot instantiate my class unless I provide a null value or method to the constructor. Is making a private default constructor redundant in this case?

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace fAloha.Core
{
  public class NotifyVector<T>
  {
    public delegate void NotifyCBR();
    private Action notifyCbr_ = () => { }; // Noop;
    private System.Collections.Generic.List<T> vector_;
    private readonly Object dataSyncObject_ = new object();
    private readonly object notifySyncObject_ = new object();
    private volatile bool asyncNotfyInProgress_ = false;


    // Class Instantiation requires a Callback routine
    public NotifyVector(Action cbr)
    {
      if (cbr != null)
        notifyCbr_ = cbr;
      vector_ = new System.Collections.Generic.List<T>();
    }

    // Notify the Observer by asynchronous invocation of cbr
    // Lock is used to reduce notifications. A producer could
    // looping and adding many items adding one at a time.
    public void Notify()
    {
      if (asyncNotfyInProgress_ == false)
      {
        lock (notifySyncObject_)
        {
          asyncNotfyInProgress_ = true;
          Task.Run(async () =>
          {
            await Task.Delay(TimeSpan.FromTicks(1));
            notifyCbr_();
          }).ContinueWith(AsyncResult =>
          {
            asyncNotfyInProgress_ = false;
          });
        }
      }
    }

    // Threadsafe add for vector
    public void AddObject(T obj)
    {
      lock (dataSyncObject_)
      {
        vector_.Add(obj);
      }
    }

    // Threadsafe pop Objects from vector (swap all objects to Observer)
    public bool PopObjects(ref System.Collections.Generic.List<T> inlist)
    {
      bool retval = false;
      lock (dataSyncObject_)
      {
        if (vector_.Count > 0)
        {
          inlist = vector_;
          vector_ = new System.Collections.Generic.List<T>();
          retval = true;
        }
      }
      return retval;
     }
  }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Why the await Task.Delay(TimeSpan.FromTicks(1)); ? \$\endgroup\$ – VisualMelon May 13 at 22:18
  • \$\begingroup\$ Probably to make the task run asynchronous on a different thread. Normally you would use Task.Yield() for that. \$\endgroup\$ – Limeray May 14 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.