1

I have a class

    public class ProductionQueue
    {
        /// <summary>
        /// Gets or sets the title.
        /// </summary>
        /// <value>
        /// The title.
        /// </value>
        public string? Name { get; set; }

        /// <summary>
        /// Maximum capacity of the queue. Keep it null for inifinte capacity.
        /// </summary>
        public TimeSpan? Capacity { get; set; }

        /// <summary>
        /// Gets or sets the tasks.
        /// </summary>
        /// <value>
        /// The tasks.
        /// </value>
        public IList<Task> Tasks { get; set; } = new List<Task>();
    }

Let me just explain that the Task object also contains a variable (probably another Timespan) that contains the time to perform the task.

Is it possible to add an event, an observer or any other behaviour in my ProductionQueue to throw an exception if my Capacity is reached when I add a new task in my Task list?

Bastien Vandamme
  • 17,659
  • 30
  • 118
  • 200
  • 1
    I would make the Tasks-List private and add methods to get/add/remove elements to the list. There you can check your limitations like capacity and handle it – TheTanic Apr 22 '22 at 07:38
  • Yeah... this is also my idea but... or inherit and override the existing add() – Bastien Vandamme Apr 22 '22 at 07:53
  • Inherit and Override is also a nice solution, if you only want List behaviour. But maybe you want to take a look at other collection like a queue. Maybe take look here: https://stackoverflow.com/a/1305/3888657 – TheTanic Apr 22 '22 at 07:55
  • 1
    My list is a production queue, not acting like a Queue. It is a very complex business queue with capacity, priorities, and FiFo system that the business can change. I will start from a classic list and add all my behaviour one by one. I just want to know if it is possible to do otherwise... with event on the add or with an observer. Something that suprise me. – Bastien Vandamme Apr 22 '22 at 08:00
  • Why not use an ObservableCollection instead of a List ? – XouDo Apr 22 '22 at 08:12

1 Answers1

1

I have written this simple solution based on your initial code but with using an ObservableCollection, so the capacity can be check every time the collection is modified.

It could be done in more effecient way using the data provided by NotifyCollectionChangedEventArgs (type of modification, NewItems, OldItems etc.) to recompute only what's changed, instead of iterating through the whole collection every time.

   // simple object for the sake of this example
   public class Task
   {
       public TimeSpan TimeToPerform;
   }

   public class ProductionQueue
   {
       public string? Name { get; set; }

       /// <summary>
       /// Maximum capacity of the queue. Keep it null for inifinte capacity.
       /// </summary>
       public TimeSpan? Capacity { get; set;}
               
       public ObservableCollection<Task> Tasks = new ObservableCollection <Task>();
       
       // ProductionQueue ctor
       public ProductionQueue(TimeSpan? initialCapacity)
       {
           this.Capacity = initialCapacity;

           // subscribe to know when the collection gets changed
           this.Tasks.CollectionChanged += (s, e) => { 
               Console.WriteLine("collection changed");               
               this.checkCapacity();                
           };  
       } 
       
       private void checkCapacity()
       {
           var totalTime = TimeSpan.Zero;
               
           foreach (var task in this.Tasks)
           {
               totalTime+= task.TimeToPerform;
           }
           
           if (totalTime > this.Capacity)
               throw new Exception("queue time capacity exceeded");           
       }
   }
}

And here is an example of program using it:

public static void Main(string[] args)
{
    try
    {
        var PQ = new ProductionQueue(TimeSpan.FromHours(1));

        PQ.Tasks.Add(new Task(){ TimeToPerform=TimeSpan.FromMinutes(40)});
        PQ.Tasks.Add(new Task(){ TimeToPerform=TimeSpan.FromMinutes(30)});

        Console.WriteLine("Tasks added without problem");
    }
    catch(Exception e)
    {
        Console.WriteLine("Exception occured: "+e.Message);
    }
}

Console output:

collection changed
collection changed
Exception occured: queue time capacity exceeded
XouDo
  • 945
  • 10
  • 19