private void Handle(CaseInstanceWorkerTaskAddedEvent evt) { var child = GetCasePlanItem(evt.CasePlanInstanceElementId); if (child == null) { throw new AggregateValidationException(new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("validation", $"unknown child '{evt.CasePlanInstanceElementId}'") }); } WorkerTasks.Add(new CasePlanInstanceWorkerTask { CasePlanElementInstanceId = evt.CasePlanInstanceElementId, CreateDateTime = evt.CreateDateTime }); UpdateDateTime = evt.CreateDateTime; Version = evt.Version; }
public async Task <TRet> PerformWorkerOperationAsync <TRet>(Func <INode <TState, TCost>, Task <TRet> > acquiredoperations) { //System.Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: Getting node."); INode <TState, TCost> myitem; await ConsumerLock.WaitAsync(); bool hasconsumerlock = true; try { Monitor.Enter(ProducerLock); while (Nodes.Count <= 0) { Monitor.Exit(ProducerLock); List <Task> MonitoredTasks = new List <Task>(WorkerTasks); if (MonitoredTasks.Count == 0) { throw new QueueExhaustedException(); } ConsumerLock.Release(); hasconsumerlock = false; await Task.WhenAny(MonitoredTasks); await ConsumerLock.WaitAsync(); hasconsumerlock = true; Monitor.Enter(ProducerLock); } myitem = Nodes[0]; Nodes.RemoveAt(0); VisitedStates.Add(myitem.State, myitem.AccumulatedCost); Monitor.Exit(ProducerLock); } catch (Exception) { if (hasconsumerlock) { ConsumerLock.Release(); } throw; } //Still has consumerlock TaskCompletionSource <int> holder = new TaskCompletionSource <int>(); async Task <TRet> Worker(INode <TState, TCost> n) { await holder.Task; return(await acquiredoperations(n)); } var t = Worker(myitem); var cleanuptask = t.ContinueWith(async x => { await ConsumerLock.WaitAsync(); WorkerTasks.Remove(x); ConsumerLock.Release(); }); WorkerTasks.Add(t); ConsumerLock.Release(); holder.SetResult(0); //release hold await cleanuptask; return(await t); }