/// <summary> /// Get an abortable thread from the pool. Wait until Run() is called on the returned IThreadControl. /// </summary> /// <param name="work">actual work to be executed by this thread</param> /// <param name="arg">application arg</param> /// <param name="done">called when the work is finished</param> /// <returns>control object for the abortable thread</returns> public IThreadControl GetThread(WaitCallback work, object arg, CompletionCallback done) { ThreadControl ctl; lock (_Sync) { if (_Free.Count > 0) { ctl = _Free.Pop(); ctl.Proc = work; ctl.Arg = arg; } else if (_Busy.Count < _Capacity) { ctl = new ThreadControl(_Prefix, this) { Proc = work, Arg = arg }; ctl.Start(); } else return null; _Busy.Add(ctl); } ctl.OnCompletion = done; return ctl; }
public void Start(int minThreads, int maxThreads) { lock (_Sync) { if (_Recycler != null && _Recycler.IsAlive) throw new InvalidOperationException("Thread pool already initialized"); _Capacity = maxThreads; _Free = new Stack<ThreadControl>(maxThreads); _Busy = new HashSet<ThreadControl>(); _Run = true; _Recycler = new Thread(RecyclerAborter) { Name = _Prefix + "-recycler", IsBackground = true }; _Recycler.Start(); for (int i = 0; i < minThreads; i++) { var ctl = new ThreadControl(_Prefix, this); _Free.Push(ctl); ctl.Start(); } } }