.Net 线程

  • .Net 线程已关闭评论
  • 266 次浏览
  • A+
所属分类:.NET技术
摘要

一个应用程序中,必须有一个进程,一个进程可同时多个线程协作处理。同步:单线程,每一步都执行结束并返回结果,下一步处于等待,阻塞程序流

一个应用程序中,必须有一个进程,一个进程可同时多个线程协作处理。

同步:单线程,每一步都执行结束并返回结果,下一步处于等待,阻塞程序流

异步:多线程,不需要等待执行结束,可继续执行下一步,形成并行处理,无序的不可预测的执行顺序

前台线程:主线程退出后,子线程直至完成计算。

后台线程:主线程退出后,子线程也会停止退出。

 

线程的应用

常用的线程创建方式

  • new Thread
  • ThreadPool.QueueUserWorkItem 后台线程
  • delegate 委托 invoke
  • Task.Run / Task.Factory.StartNewd
  • Parallel
  • await / async

 

ThreadPool 线程池

每个进程都有一个线程池,每个线程池依环境因素分配不同的线程数
由线程池统一管理每个线程的创建/分配/销毁。

// 设置最大线程数 ThreadPool.SetMaxThreads // 用线程池中的后台线程执行方法 ThreadPool.QueueUserWorkItem(方法1);

 

Task

Action<object> action = (object obj) => {     Console.WriteLine("Task={0}, obj={1}, Thread={2}",     Task.CurrentId, obj,     Thread.CurrentThread.ManagedThreadId); };  // Create a task but do not start it. Task t1 = new Task(action, "alpha");  // Construct a started task Task t2 = Task.Factory.StartNew(action, "beta"); // Block the main thread to demonstrate that t2 is executing t2.Wait();  // Launch t1  t1.Start(); Console.WriteLine("t1 has been launched. (Main Thread={0})", Thread.CurrentThread.ManagedThreadId); // Wait for the task to finish. t1.Wait();  // Construct a started task using Task.Run. String taskData = "delta"; Task t3 = Task.Run( () => {     Console.WriteLine("Task={0}, obj={1}, Thread={2}",     Task.CurrentId, taskData,     Thread.CurrentThread.ManagedThreadId); }); // Wait for the task to finish. t3.Wait();  // Construct an unstarted task Task t4 = new Task(action, "gamma"); // Run it synchronously t4.RunSynchronously(); // Although the task was run synchronously, it is a good practice // to wait for it in the event exceptions were thrown by the task. t4.Wait();

 

Parallel

多线程并行处理的 Parallel.Invoke,Parallel.For,Parallel.ForEach;无法确保顺序处理。

class Program {      static void Main(string[] args)     {         List<Product> ProductList = GetProcuctList();                  // 示例 ForEach 无序处理         Parallel.ForEach(ProductList, (model) => {             Console.WriteLine(model.Name);         });                  // 示例:并行运行方法         Parallel.Invoke(方法1, 方法2, () => 方法3, () => 方法4);                  Console.ReadLine();     }          // demo     private static List<Product> GetProcuctList()     {          List<Product> result = new List<Product>();         // 示例 For 无序处理         Parallel.For(1, 100, index =>         {             Product model = new Product();             model.Category = "Category" + index;             model.Name = "Name" + index;             ProductList.Add(model);             Console.WriteLine("ForSetProcuct SetProcuct index: {0}", index);         });                  return result;     }  }  class Product {     public string Name { get; set; }     public string Category { get; set; } }

 

await / async

创建后台进程并行处理,并取得处理结果。

// 执行 async 方法(后台线程执行) Task<string> _task_result_1 = t1.Func1(); // 主线程不等返回结果,继续往下执行  // 执行方法 string _result_2 = t1.Func2(); // 以上两个方法并行执行  // 取 Func1 的运行结果 string _result_1 = await _task_result_1;  // 整合两个方法的运行结果 int _total_ = _result_1.length + _result_2.length;

 

常用的线程锁

lock

封装自应用级锁Monitor类,需要有线程共享的锁标识,告知其它线程是否等待。

 

Monitor

程序级锁,于单个应用范围内

// 给要操作的对象加把锁,排他锁 Monitor.Enter(T); // 释放当前锁,允许其它线程使用了 Monitor.Exit(T);

 

Semaphore

限制可同时访问某一资源或资源池的线程数,允许同时共享的线程数

// 创建时,定义同时的默认线程数和最多线程数 Semaphore sem = new Semaphore(1, 20); // 上锁 sem.WaitOne(); // 释放锁(一次释放线程数) sem.Release(3);

 

Mutex

系统级锁,内核对象,所以可跨进程跨应用
// 阻挡锁住当前块,其它线程处于等待 // 超时后返回false,不允许其它线程进入 Mutex.WaitOne(timeout); // 释放当前,一个,允许其它线程进入 Mutex.ReleaseMutex();

 

线程安全

线程安全的类,通过 lock(xxx.SyncRoot) 实现线程同步,如:Array,ArrayList

线程安全的高性能集合类

ConcurrentBag 无序集合

ConcurrentStack 后进先出

ConcurrentQueue 先进先出

ConcurrentDictionary 键值对字典