1.任务StartNew后就开始执行,使用Wait()来确保任务结束后继续
static void Main(string[] args) { try { int numberOfUsers = 100; var users = new string[20]; for (int i = 0; i < 20; i++) { users[i] = string.Format("LoadTest{0}", i + 1); } Task t = Task.Factory.StartNew(() => WriteLog(users[5])); Thread.Sleep(5000); Console.WriteLine("Is first one start?"); Task t1 = Task.Factory.StartNew(() => WriteLog(users[6])); Thread.Sleep(5000); Console.WriteLine("Are they start?"); Thread.Sleep(5000); t1.Wait(); Console.WriteLine("Will End soon!"); t.Wait(); Thread.Sleep(500000000); } catch (Exception ex) { Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message)); Thread.Sleep(500000000); } } private static void WriteLog(string userName) { Console.WriteLine(string.Format("Begin Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId)); Thread.Sleep(5000); if (userName == "LoadTest2") { Thread.Sleep(5000); throw new Exception("Lazy!"); } Console.WriteLine(string.Format("End Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId)); }
执行效果:
使用ThreadPool也是同样效果:
foreach (string user in users) { ThreadPool.QueueUserWorkItem(arg => { WriteLog(user); }); }
2.10个任务一起执行,须注意WriteLog的参数不能直接使用i,因为在实际开始工作的时候i值已经变成了10
Task[] ts = new Task[10]; for(int i=0;i < numberOfUsers ; i++ ) { ts[i] = Task.Factory.StartNew((object obj) => { int j = (int)obj; WriteLog(users[j]); }, i); } Task.WaitAll(ts); Console.WriteLine("Will End soon!"); Thread.Sleep(500000000);
3.总共20个人,后10个人接着前面10个人后干活,使用ContinueWith , 其中传的prevTask可以得到前面任务的状态
static void Main(string[] args) { try { int numberOfUsers = 10; var users = new string[20]; for (int i = 0; i < 20; i++) { users[i] = string.Format("LoadTest{0}", i + 1); } Task[] ts = new Task[numberOfUsers]; for (int i = 0; i < numberOfUsers; i++) { ts[i] = Task.Factory.StartNew((object obj) => { int j = (int)obj; WriteLog(users[j]); }, i).ContinueWith((prevTask) => { string exp = string.Empty; if (prevTask.Exception!=null ) exp = "Exception:" + prevTask.Exception.Message; Console.WriteLine(string.Format("ID:{0} Status:{1} IsCanceled:{2} IsCompleted:{3} {4}", prevTask.Id, prevTask.Status, prevTask.IsCanceled, prevTask.IsCompleted, exp)); WriteLog(users[9 + prevTask.Id]); }); } Task.WaitAll(ts); Console.WriteLine("Will End soon!"); Thread.Sleep(500000000); } catch (Exception ex) { Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message)); Thread.Sleep(500000000); } }
4.获取UI上的值来控制是否cancel一个任务下面的所有子任务,使用CancellationTokenSource
static void Main(string[] args) { try { int numberOfUsers = 10; var users = new string[numberOfUsers]; for (int i = 0; i < numberOfUsers; i++) { users[i] = string.Format("LoadTest{0}", i + 1); } CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; ConcurrentBag<Task> ts = new ConcurrentBag<Task>(); Console.WriteLine("Press any key to begin tasks..."); Console.WriteLine("To terminate the example, press 'c' to cancel and exit..."); Console.ReadKey(); Console.WriteLine(); //Task t = Task.Factory.StartNew(() => WriteLog(users[0], token), token); //Console.WriteLine("Task {0} executing", t.Id); //ts.Add(t); Task t = Task.Factory.StartNew(() => { Task tc; for (int i = 0; i < numberOfUsers; i++) { tc = Task.Factory.StartNew((object obj) => { int j = (int)obj; WriteLog(users[j], token); }, i, token); ts.Add(tc); } },token); ts.Add(t); if (Console.ReadKey().KeyChar == 'c') { tokenSource.Cancel(); Console.WriteLine(" Task cancellation requested."); } try { Task.WaitAll(ts.ToArray()); } catch (AggregateException e) { foreach (var v in e.InnerExceptions) { if (v is TaskCanceledException) Console.WriteLine(" TaskCanceledException: Task {0}", ((TaskCanceledException)v).Task.Id); else Console.WriteLine(" Exception: {0}", v.GetType().Name); } } Console.WriteLine("Will End soon!"); Thread.Sleep(500000000); } catch (Exception ex) { Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message)); Thread.Sleep(500000000); } } private static void WriteLog(string userName, CancellationToken ct) { Console.WriteLine(string.Format("Begin Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId)); if (userName != "LoadTest1" && userName != "LoadTest2" && userName != "LoadTest3") { Thread.Sleep(5000); } if (ct.IsCancellationRequested) { Console.WriteLine(string.Format("Cancel :{0} ThreadId {1}", userName, Thread.CurrentThread.ManagedThreadId)); ct.ThrowIfCancellationRequested(); } Console.WriteLine(string.Format("End Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId)); }
5.总共10个任务,每次最多3个任务,每当这3个任务中任何一个完成,就会从后续任务中拿出任务来做
static void Main(string[] args) { try { int numberOfUsers = 10; var users = new string[numberOfUsers]; for (int i = 0; i < numberOfUsers; i++) { users[i] = string.Format("LoadTest{0}", i + 1); } Action[] aArr = new Action[numberOfUsers]; int j = 0 ; for (int i = 0; i < numberOfUsers; i++){ aArr[i] = new Action(() => WriteLog(users[j++])); } System.Threading.Tasks.ParallelOptions po = new ParallelOptions(); po.MaxDegreeOfParallelism = 3; try { System.Threading.Tasks.Parallel.Invoke(po, aArr); } catch (AggregateException e) { foreach (var v in e.InnerExceptions) { if (v is TaskCanceledException) Console.WriteLine(" TaskCanceledException: Task {0}", ((TaskCanceledException)v).Task.Id); else Console.WriteLine(" Exception: {0}", v.Message); } } Console.WriteLine("Will End soon!"); Thread.Sleep(500000000); } catch (Exception ex) { Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message)); Thread.Sleep(500000000); } }
6.总共10个任务,每次最多3个任务,而且每次必须3个一起开始
static void Main(string[] args) { try { int numberOfUsers = 10; int maxConcurrent = 3; var users = new string[numberOfUsers]; for (int i = 0; i < numberOfUsers; i++) { users[i] = string.Format("LoadTest{0}", i + 1); } int itemProcessed = 0; int loopCnt = 0; do { List<Task> taskList = new List<Task>(); for (int i = 0; i < maxConcurrent; i++) { taskList.Add(Task.Factory.StartNew((object obj) => { int j = (int)obj; try { if (loopCnt * maxConcurrent + j < numberOfUsers) { WriteLog(users[loopCnt * maxConcurrent + j]); } } catch (Exception ex) { Console.WriteLine(string.Format("{0} encounter error :{1}", users[loopCnt * maxConcurrent + j],ex.Message )); } } ,i)); Interlocked.Increment(ref itemProcessed); } Task.WaitAll(taskList.ToArray()); loopCnt++; } while (itemProcessed < numberOfUsers); Console.WriteLine("Will End soon!"); Thread.Sleep(500000000); } catch (Exception ex) { Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message)); Thread.Sleep(500000000); } }
7.每次最多3个user一起干活
!wrong
static void Main(string[] args) { ThreadPool.SetMaxThreads(1, 100); int numberOfUsers = 10; int maxWorkUsers = 3; var users = new string[numberOfUsers]; for (int i = 0; i < numberOfUsers; i++) { users[i] = string.Format("LoadTest{0}", i + 1); } var options = new ParallelOptions(); options.MaxDegreeOfParallelism = maxWorkUsers; Parallel.ForEach(users, options, (user) => { WriteLog(user); }); Thread.Sleep(500000000); }
correct
static void Main(string[] args) { try { int numberOfUsers = 10; var users = new string[numberOfUsers]; for (int i = 0; i < numberOfUsers; i++) { users[i] = string.Format("LoadTest{0}", i + 1); } Action[] aArr = new Action[numberOfUsers]; int j = 0 ; for (int i = 0; i < numberOfUsers; i++){ aArr[i] = new Action(() => WriteLog(users[j++])); } System.Threading.Tasks.ParallelOptions po = new ParallelOptions(); po.MaxDegreeOfParallelism = 3; try { System.Threading.Tasks.Parallel.Invoke(po, aArr); } catch (AggregateException e) { foreach (var v in e.InnerExceptions) { if (v is TaskCanceledException) Console.WriteLine(" TaskCanceledException: Task {0}", ((TaskCanceledException)v).Task.Id); else Console.WriteLine(" Exception: {0}", v.Message); } } Console.WriteLine("Will End soon!"); Thread.Sleep(500000000); } catch (Exception ex) { Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message)); Thread.Sleep(500000000); } } private static void WriteLog(string userName) { Console.WriteLine(string.Format("Begin Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId)); Thread.Sleep(5000); if (userName == "LoadTest2") { Thread.Sleep(5000); throw new Exception("Lazy!"); } Console.WriteLine(string.Format("End Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId)); }
8.多線程改變某值
private static List<string> testList = new List<string>(); private static void AddList(string name) { testList.Add(name); } static void test2() { int threadcount = 10; List<Thread> threads = new List<Thread>(); for (int i = 0; i < threadcount; i++) { Thread t = new Thread(delegate(object parameter) { EmpServiceDataContext db = new EmpServiceDataContext(); int _i = (int)parameter; int index = 0; for( int k = 0 ; k < 20000 ; k++) { if (index % threadcount == _i) { try { AddList("Thread" + k); } catch (Exception ex) { } } index++; } }); t.Name = string.Format("SendEmailThread_{0}", i); threads.Add(t); t.Start(i); } foreach (Thread t in threads) { t.Join(); } } Task t = Task.Factory.StartNew(() => test2()); t.Wait();
9.volatile 和 Interlocked
http://baike.baidu.com/view/608706.htm?fr=aladdin
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
Interlocked.Decrement(ref JOB_COUNT);
10. ThreadStartStop
如何:创建和终止线程(C# 编程指南)
http://msdn.microsoft.com/zh-cn/library/7a2f3ay4(VS.80).aspx
public class Worker { // This method will be called when the thread is started. public void DoWork() { while (!_shouldStop) { Console.WriteLine("worker thread: working..."); } Console.WriteLine("worker thread: terminating gracefully."); } public void RequestStop() { _shouldStop = true; } // Volatile is used as hint to the compiler that this data // member will be accessed by multiple threads. private volatile bool _shouldStop; } public class WorkerThreadExample { static void Main() { // Create the thread object. This does not start the thread. Worker workerObject = new Worker(); Thread workerThread = new Thread(workerObject.DoWork); // Start the worker thread. workerThread.Start(); Console.WriteLine("main thread: Starting worker thread..."); // Loop until worker thread activates. while (!workerThread.IsAlive); // Put the main thread to sleep for 1 millisecond to // allow the worker thread to do some work: Thread.Sleep(1); // Request that the worker thread stop itself: workerObject.RequestStop(); // Use the Join method to block the current thread // until the object's thread terminates. workerThread.Join(); Console.WriteLine("main thread: Worker thread has terminated."); } }