Example #1
0
 /// <summary> Adds a unit of work to the list </summary>
 public void AddWork(IWaitAndContinue item)
 {
     if (_control.HasQuit)
     {
         throw new ObjectDisposedException(GetType().FullName);
     }
     _work.AddWork(item);
     _control.Modified();
 }
Example #2
0
        private void Remove(ref Node node)
        {
            IWaitAndContinue item = node.Value;

            lock (_list)
                _list.Remove(node);
            node.Value = null;
            node       = null;
            item.Dispose();
        }
 /// <summary> Adds a unit of work to the list </summary>
 public void AddWork(IWaitAndContinue item)
 {
     if (_disposed) throw new ObjectDisposedException(GetType().FullName);
     Check.NotNull(item);
     if (item.Completed)
     {
         item.Dispose();
         return;
     }
     lock (_list)
         _list.AddLast(item);
 }
Example #4
0
 /// <summary> Adds a unit of work to the list </summary>
 public void AddWork(IWaitAndContinue item)
 {
     if (_disposed)
     {
         throw new ObjectDisposedException(GetType().FullName);
     }
     Check.NotNull(item);
     if (item.Completed)
     {
         item.Dispose();
         return;
     }
     lock (_list)
         _list.AddLast(item);
 }
Example #5
0
        /// <summary>
        /// Returns true if a unit of work was processed within the timeout, or false if
        /// the timeout expired prior to a unit of work completion.  itemProcessed will
        /// be set to the instance of the item process when the result is true.
        /// </summary>
        public bool PerformWork(int timeout, out IWaitAndContinue itemProcessed)
        {
            itemProcessed = null;
            Node next;

            if (_handles == null)
            {
                int count = 0;
                next = _list.First;
                while (next != null)
                {
                    Node             node = next;
                    IWaitAndContinue item = next.Value;
                    next = next.Next;

                    try { count += item.HandleCount; }
                    catch
                    {
                        Remove(ref node);
                        throw;
                    }
                }
                if (count == 0)
                {
                    return(false);
                }
                _handles = _handles ?? new WaitHandle[count];
                _workers = _workers ?? new Node[count];
            }

            int offset = 0;

            next = _list.First;
            while (next != null)
            {
                Node             node = next;
                IWaitAndContinue item = next.Value;
                next = next.Next;

                try
                {
                    if (item.Completed)
                    {
                        Remove(ref node);
                        continue;
                    }
                    int handleCount = item.HandleCount;
                    if (handleCount == 0)
                    {
                        continue; //not yet available
                    }
                    if ((offset + handleCount) > 64)
                    {
                        break; //not enough room, WaitHandle.WaitAny requires no more than 64 handles
                    }
                    if (_handles.Length < (offset + handleCount))
                    {
                        Array.Resize(ref _handles, offset + handleCount);
                        Array.Resize(ref _workers, offset + handleCount);
                    }

                    item.CopyHandles(_handles, offset);

                    for (int ix = 0; ix < handleCount; ix++)
                    {
                        _workers[offset++] = node;
                    }
                }
                catch
                {
                    Remove(ref node);
                    throw;
                }
            }

            if (offset == 0)
            {
                return(false);
            }
            if (_handles.Length != offset)
            {
                Array.Resize(ref _handles, offset);
                Array.Resize(ref _workers, offset);
            }

            Node       itemSignaled;
            WaitHandle handleSignaled;

            try
            {
                int response = WaitHandle.WaitAny(_handles, timeout, true);
                if (response == WaitHandle.WaitTimeout)
                {
                    return(false);
                }
                handleSignaled = _handles[response];
                itemSignaled   = _workers[response];
            }
            catch (ObjectDisposedException)
            { return(false); }
            catch (AbandonedMutexException ae)
            {
                if (ae.Mutex == null || ae.MutexIndex < 0 || ae.MutexIndex >= _workers.Length)
                {
                    throw;
                }
                handleSignaled = ae.Mutex;
                itemSignaled   = _workers[ae.MutexIndex];
            }

            itemProcessed = itemSignaled.Value;
            try { itemProcessed.ContinueProcessing(handleSignaled); }
            catch
            {
                Remove(ref itemSignaled);
                throw;
            }
            if (itemProcessed.Completed)
            {
                Remove(ref itemSignaled);
            }

            return(true);
        }
        /// <summary>
        /// Returns true if a unit of work was processed within the timeout, or false if
        /// the timeout expired prior to a unit of work completion.  itemProcessed will
        /// be set to the instance of the item process when the result is true.
        /// </summary>
        public bool PerformWork(int timeout, out IWaitAndContinue itemProcessed)
        {
            itemProcessed = null;
            Node next;
            if (_handles == null)
            {
                int count = 0;
                next = _list.First;
                while (next != null)
                {
                    Node node = next;
                    IWaitAndContinue item = next.Value;
                    next = next.Next;

                    try { count += item.HandleCount; }
                    catch
                    {
                        Remove(ref node);
                        throw;
                    }
                }
                if (count == 0)
                    return false;
                _handles = _handles ?? new WaitHandle[count];
                _workers = _workers ?? new Node[count];
            }

            int offset = 0;
            next = _list.First;
            while (next != null)
            {
                Node node = next;
                IWaitAndContinue item = next.Value;
                next = next.Next;

                try
                {
                    if (item.Completed)
                    {
                        Remove(ref node);
                        continue;
                    }
                    int handleCount = item.HandleCount;
                    if (handleCount == 0)
                        continue; //not yet available
                    if ((offset + handleCount) > 64)
                        break; //not enough room, WaitHandle.WaitAny requires no more than 64 handles
                    if (_handles.Length < (offset + handleCount))
                    {
                        Array.Resize(ref _handles, offset + handleCount);
                        Array.Resize(ref _workers, offset + handleCount);
                    }

                    item.CopyHandles(_handles, offset);

                    for (int ix = 0; ix < handleCount; ix++)
                        _workers[offset++] = node;
                }
                catch
                {
                    Remove(ref node);
                    throw;
                }
            }

            if (offset == 0)
                return false;
            if (_handles.Length != offset)
            {
                Array.Resize(ref _handles, offset);
                Array.Resize(ref _workers, offset);
            }

            Node itemSignaled;
            WaitHandle handleSignaled;
            try
            {
                int response = WaitHandle.WaitAny(_handles, timeout, true);
                if (response == WaitHandle.WaitTimeout)
                    return false;
                handleSignaled = _handles[response];
                itemSignaled = _workers[response];
            }
            catch (ObjectDisposedException)
            { return false; }
            catch (AbandonedMutexException ae)
            {
                if (ae.Mutex == null || ae.MutexIndex < 0 || ae.MutexIndex >= _workers.Length)
                    throw;
                handleSignaled = ae.Mutex;
                itemSignaled = _workers[ae.MutexIndex];
            }

            itemProcessed = itemSignaled.Value;
            try { itemProcessed.ContinueProcessing(handleSignaled); }
            catch
            {
                Remove(ref itemSignaled);
                throw;
            }
            if (itemProcessed.Completed)
                Remove(ref itemSignaled);

            return true;
        }
 /// <summary> Adds a unit of work to the list </summary>
 public void AddWork(IWaitAndContinue item)
 {
     if (_control.HasQuit) throw new ObjectDisposedException(GetType().FullName);
     _work.AddWork(item);
     _control.Modified();
 }