/// <summary> /// Adds the item to the queue to process asynchronously and /// uses the different operation instead of the default. /// </summary> /// <param name="item">the item to enqueue</param> /// <param name="opp">the new operation that overrides the default</param> /// <exception cref="System.ArgumentNullException">opp is null</exception> public void EnQueue(T item, QueueOperationHandler <T> opp) { if (opp == null) { throw new ArgumentNullException("operation can not be null"); } lock (syncobj) { if (qs == QueueState.Idle) { #region idle qs = QueueState.Running; QueueStateChangedInternal(this, new QueueChangedState(QueueState.Idle, QueueState.Running)); /// the problem with generics is that sometimes the fully /// descriptive name goes on for a while KeyValuePair <T, QueueOperationHandler <T> > kvp = new KeyValuePair <T, QueueOperationHandler <T> >(item, opp); /// thread demands that its ParameterizedThreadStart take an object not a generic type /// one might have resonably thought that there would be a generic constructor that /// took a strongly typed value but there is not one currentthreads++; new Thread(new ParameterizedThreadStart(RunOpp)).Start(kvp); #endregion } else if ((qs == QueueState.Paused) || (qs == QueueState.Pauseing)) { #region pause /// in the case that we are pausing or currently paused we just add the value to the /// queue we dont try to run the process queue.Enqueue(new KeyValuePair <T, QueueOperationHandler <T> >(item, opp)); #endregion } else if (qs == QueueState.Running) { #region running /// you have to enqueue the item then try to execute the first item in the process /// always enqueue first as this ensures that you get the oldest item first since /// that is what you wanted to do you did not want a stack queue.Enqueue(new KeyValuePair <T, QueueOperationHandler <T> >(item, opp)); TryNewThread(); #endregion } else if (qs == QueueState.Stopping) { #region stopping /// when you are stopping the queue i assume that you wanted to stop it not pause it this /// means that if you try to enqueue something it will throw an exception since you /// shouldnt be enqueueing anything since when the queue gets done all its current /// threads it clears the rest out so why bother enqueueing it. at this point we have /// a choice we can make the notifyer die or we can use the error event we already /// have built in to tell the sender. i chose the later. also try to pick an appropriate /// exception not just the base ThreadErrorInternal(item, new ThreadStateException("the Queue is stopping . no processing done")); #endregion } } }
/// <summary> /// Abort thread for a specific item/operation combination. /// </summary> /// <param name="Item"></param> /// <param name="operation"></param> public void Abort(T Item, QueueOperationHandler <T> operation) { KeyValuePair <T, QueueOperationHandler <T> > kvp = new KeyValuePair <T, QueueOperationHandler <T> >(Item, operation); Abort(kvp); }
/// <summary> /// constructs the NotifyingThreadQueue. sets the state to QueueState.Idle /// </summary> /// <param name="maxthreads">sets the maximum number of simultaneous operations</param> /// <param name="defaultoperation">the default operation to perform on an enqueued item</param> /// <exception cref="System.ArgumentException">maxthreads is less than or equal to 0</exception> /// <exception cref="System.ArgumentNullException">defaultoperation is null</exception> public NotifyingThreadQueue(int maxthreads, QueueOperationHandler <T> defaultoperation) { if (maxthreads <= 0) { throw new ArgumentException("maxthreads can not be <= 0"); } if (defaultoperation == null) { throw new ArgumentNullException("defaultoperation can not be null"); } this.qs = QueueState.Idle; this.syncobj = new object(); this.currentthreads = 0; this.maxthreads = maxthreads; this.queue = new Queue <KeyValuePair <T, QueueOperationHandler <T> > >(); this.defaultop = defaultoperation; }
/// <summary> /// constructs the NotifyingThreadQueue. sets the state to QueueState.Idle /// </summary> /// <param name="defaultoperation">the default operation to perform on an enqueued item</param> /// <exception cref="System.ArgumentNullException">defaultoperation is null</exception> public NotifyingThreadQueue(QueueOperationHandler <T> defaultoperation, object extraInfo) : this(int.MaxValue, defaultoperation) { _extraInfo = extraInfo; }
/// <summary> /// constructs the NotifyingThreadQueue. sets the state to QueueState.Idle /// </summary> /// <param name="defaultoperation">the default operation to perform on an enqueued item</param> /// <exception cref="System.ArgumentNullException">defaultoperation is null</exception> public NotifyingThreadQueue(QueueOperationHandler <T> defaultoperation) : this(int.MaxValue, defaultoperation) { }