应朋友之邀,写了一个多线程执行多任务的例子。这个场景应用比较普遍,
比如多个线程下载多个文件,比如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);
-
- 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>
- {
- }
(michael-zhangyu) |