应朋友之邀,写了一个多线程执行多任务的例子。这个场景应用比较普遍,
比如多个线程下载多个文件,比如3个线程下载10个文件,比如10个线程执行1000条任务队列;
Demo代码如下:
public partial class Form1 : Form { private ThreadProxy _threadsProxy = null; ExpressCollection list = new ExpressCollection(); public Form1() { InitializeComponent(); _threadsProxy = new ThreadProxy(3, list); _threadsProxy.ExpressComputed += new EventHandler<ExpressComputedEventArgs>(_threadsProxy_ExpressComputed); } private void button1_Click(object sender, EventArgs e) { list.Clear(); _threadsProxy.Stop(); list.Add(new Express(1, 1)); list.Add(new Express(1, 2)); list.Add(new Express(1, 3)); list.Add(new Express(1, 4)); list.Add(new Express(1, 5)); list.Add(new Express(1, 6)); list.Add(new Express(1, 7)); list.Add(new Express(1, 8)); list.Add(new Express(1, 9)); list.Add(new Express(1, 10)); list.Add(new Express(1, 11)); list.Add(new Express(1, 12)); list.Add(new Express(1, 13)); list.Add(new Express(1, 14)); Console.WriteLine("启动线程..........................."); _threadsProxy.Run(); } private void button2_Click(object sender, EventArgs e) { if (_threadsProxy != null) { Console.WriteLine("测试暂停..........................."); _threadsProxy.Stop(); } } void _threadsProxy_ExpressComputed(object sender, ExpressComputedEventArgs e) { Console.WriteLine(string.Format("ThreadID:{0} {1} + {2} = {3}", Thread.CurrentThread.ManagedThreadId, e.Express.A, e.Express.B, e.Result)); } }
public class ThreadProxy : IDisposable { private int _threadCount = 1; ExpressCollection _list; private Thread[] _threads = null; private bool _isRun = false; public ThreadProxy(ExpressCollection list) { _list = list; } public ThreadProxy(int threadCount, ExpressCollection list) : this(list) { _threadCount = threadCount; _threads = CreateThreadCollection(); } public void Run() { if (!_isRun && _list != null && _list.Count>0) { _isRun = true; for (int i = 0; i < _threadCount; i++) { _threads[i] = new Thread(new ThreadStart(ThreadInvoke)); _threads[i].IsBackground = true; _threads[i].Start(); } } } protected virtual Thread[] CreateThreadCollection() { return new Thread[_threadCount]; } public void Stop() { _isRun = false; } private void ThreadInvoke() { try { while (_isRun) { Express express = _list.GetNext(); if (express != null) { int result = express.A + express.B; OnExpressComputed(result, express); //do something Thread.Sleep(1000);//测试暂停 } else { break; } } } catch (ThreadAbortException) { Thread.ResetAbort(); return; } catch (Exception) { //记录日志 } } public event EventHandler<ExpressComputedEventArgs> ExpressComputed; protected virtual void OnExpressComputed(int result ,Express express) { if (ExpressComputed != null) { ExpressComputed(this, new ExpressComputedEventArgs(result,express)); } } #region IDisposable 成员 public void Dispose() { _isRun = false; if (_threads != null) { _threads = null; } } #endregion } public class ExpressComputedEventArgs : EventArgs { private int result; public int Result { get { return result; } set { result = value; } } public ExpressComputedEventArgs(int result , Express express) { this.result = result; this.express = express; } private Express express; public Express Express { get { return express; } set { express = value; } } }
public class BaseCollection<T> : List<T> { protected readonly object _lockObj = new object(); private int index = 0; public virtual T GetNext() { T result = default(T); if (this.Count > 0 && index < Count) { lock (_lockObj)
{ result = this[index]; index++; } } return result; } public new void Add(T item) { lock (_lockObj) { base.Add(item); } } public new void Clear() { lock (_lockObj) { index = 0; base.Clear(); } } }
public class Express { private int _a; public int A { get { return _a; } set { _a = value; } } private int _b; public int B { get { return _b; } set { _b = value; } } public Express(int a, int b) { _a = a; _b = b; } }
public class ExpressCollection : BaseCollection<Express> { }