/// <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(); }
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); }
/// <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); }
/// <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(); }