public ThreadedRequest <In, Out> Post(ThreadedRequest <In, Out> request) { if (request == null) { Debug.Warn("Null request passed into Post method on threaded."); return(null); } if (request.IsInPool) { Debug.Warn("Attempt to post a request that is currently in the pool: be careful with request lifespans! A request cannot be re-used!"); return(null); } if (request.IsCancelled) { request.UponProcessed?.Invoke(ThreadedRequestResult.Cancelled, default(Out)); request.ReturnToPool(); return(null); } lock (KEY) { pending.Enqueue(request); } return(request); }
protected virtual void RunThread(object arg) { int threadIndex = (int)arg; IThreadProcessor <In, Out> processor = processors[threadIndex]; Stopwatch watch = new Stopwatch(); const int IDLE_TIME = 5; while (IsRunning) { if (pending.Count > 0) { ThreadedRequest <In, Out> todo = null; lock (KEY) { if (pending.Count > 0) { todo = pending.Dequeue(); } } if (todo != null && !todo.IsCancelled) { Statistics[threadIndex].CumulativeProcessed++; _processedIncrement++; watch.Start(); Out output = default(Out); try { output = processor.Process(todo.InputArgs); } catch (Exception) { PostResult(() => { todo.UponProcessed?.Invoke(ThreadedRequestResult.Error, output); todo.ReturnToPool(); }); continue; } PostResult(() => { todo.UponProcessed?.Invoke(ThreadedRequestResult.Run, output); todo.ReturnToPool(); }); watch.Stop(); Statistics[threadIndex].CumulativeUsage += (float)watch.Elapsed.TotalSeconds; if (Statistics[threadIndex].CumulativeUsage > 1f) { Statistics[threadIndex].CumulativeUsage = 1f; } Statistics[threadIndex].AddProcessTime((float)watch.Elapsed.TotalSeconds); watch.Reset(); } else if (todo != null && todo.IsCancelled) { PostResult(() => { todo.UponProcessed?.Invoke(ThreadedRequestResult.Cancelled, default(Out)); todo.ReturnToPool(); }); } } else { Thread.Sleep(IDLE_TIME); } } }