private int InternalSend(int waitTime, IEnumerable <string> identities, string eventName, params string[] arguments) { int count = 0; using (WaitAndContinueList work = new WaitAndContinueList()) { foreach (string identity in Check.NotNull(identities)) { IpcEventMessage m = new IpcEventMessage(this, ExecutionTimeout, identity, eventName, arguments); if (!m.Completed) { work.AddWork(m); } else { count += m.Successful ? 1 : 0; } } if (!work.IsEmpty) { //Waiting while in-call results in dead-locks, so we force these to defer if they do not complete immediatly if (InCall) { waitTime = 0; } System.Diagnostics.Stopwatch timer = null; if (waitTime > 0) { timer = new System.Diagnostics.Stopwatch(); timer.Start(); } IWaitAndContinue waitItem; int ticksRemaining = waitTime; while (work.PerformWork(ticksRemaining, out waitItem)) { count += ((IpcEventMessage)waitItem).Successful ? 1 : 0; if (waitTime > 0 && (ticksRemaining = (int)(waitTime - timer.ElapsedMilliseconds)) < 0) { break; } } if (!work.IsEmpty) { WaitAndContinueWorker worker = _deferred; if (worker != null) { try { worker.AddWork(work); } catch (ObjectDisposedException) { } } } } } return(count); }
/// <summary> Adds a unit of work to the list </summary> public void AddWork(WaitAndContinueList list) { if (_control.HasQuit) { throw new ObjectDisposedException(GetType().FullName); } _work.AddWork(list); _control.Modified(); }
/// <summary> Constructs a thread to process IWaitAndContinue work items </summary> public WaitAndContinueWorker() { _control = new WorkerControl(); _work = new WaitAndContinueList(); _work.AddWork(_control); _worker = new Thread(Run); _worker.SetApartmentState(ApartmentState.MTA); _worker.IsBackground = true; _worker.Name = GetType().Name; _worker.Start(); }
/// <summary> Moves the work in the other list into this list </summary> public void AddWork(WaitAndContinueList other) { if (_disposed) { throw new ObjectDisposedException(GetType().FullName); } lock (_list) lock (other._list) { Node next = other._list.First; while (next != null) { Node node = next; next = next.Next; other._list.Remove(node); _list.AddLast(node); } } }