当前位置: 首页 > news >正文

南皮网站建设腾讯云建站平台

南皮网站建设,腾讯云建站平台,响应式网站制设计,公司网站做的好的公司C#多线程#xff08;补充#xff09; C# 多线程的补充在C#中使用多线程1. Thread类2. 线程池3. Parallel类4. Task类启动任务接收任务的返回值同步调用指定连续任务任务的层次结构 5. BackgroundWorker控件 C# 多线程的补充 在C#中使用多线程 1. Thread类 使用Thread类通过… C#多线程补充 C# 多线程的补充在C#中使用多线程1. Thread类2. 线程池3. Parallel类4. Task类启动任务接收任务的返回值同步调用指定连续任务任务的层次结构 5. BackgroundWorker控件 C# 多线程的补充 在C#中使用多线程 1. Thread类 使用Thread类通过ThreadStart无参数或ParameterizedThreadStart一个输入参数类型的委托创建一个Thread对象开启一个新线程执行该委托传递的任务此时线程尚未处于运行状态。调用Start()函数启动线程当前线程继续执行。调用Join()函数可以阻塞当前线程直到调用Join()的线程终止。 Thread类创建的线程默认为前台线程可以通过IsBackground属性设置其为前台或后台线程。还可以通过Priority属性设置线程的优先级。 如需中止线程调用Abort()方法在调用该方法的线程上抛出ThreadAbortException异常以结束该线程。线程内部可以通过try catch捕获该异常在catch模块中进行一些必要的处理如释放持有的锁和文件资源等还可以通过Thread.ResetAbort()方法阻止线程的中止。但是通常来说应当慎重使用Abort()方法如果在当前线程中抛出该异常其结果是可预测的但是对于其他线程它会中断任何正在执行的代码有可能中断静态对象的生成造成不可预测的结果。 using System; using System.Threading;namespace ConsoleApplication1 {public class ThreadExample{public static void Main(){Thread thread new Thread(new ThreadStart(DoWork));thread.Start();//thread.Join();Thread.Sleep(10);thread.Abort();Thread parameterizedThread new Thread(new ParameterizedThreadStart(DoWorkWithParam));parameterizedThread.Start(test);Console.ReadKey();}public static void DoWork(){try{for (int i 0; i 10000; i)Console.WriteLine(Work thread: i.ToString());}catch (Exception e){Console.WriteLine(e.Message);Thread.ResetAbort();}Console.WriteLine(Work thread: still alive and working.);Thread.Sleep(1000);Console.WriteLine(Work thread: finished working.);}public static void DoWorkWithParam(object obj){string msg (string)obj;Console.WriteLine(Parameterized Work thread: msg);}} }2. 线程池 ThreadPool类维护一个线程的列表提供给用户以执行不同的小任务减少频繁创建线程的开销。ThreadPool的使用比较简单只需调用ThreadPool.QueueUserWorkItem()方法传递一个WaitCallback类型的委托线程池即从池中选择一个线程执行该任务。 public static void Main(){for (int i 0; i 5; i)ThreadPool.QueueUserWorkItem(DoWork);Console.ReadKey();}public static void DoWork(Object o){ for (int i 0; i 3; i)Console.WriteLine(loop:{0}, thread id: {1}, i, Thread.CurrentThread.ManagedThreadId);}但是线程池的使用也有一些限制 线程池中的线程均为后台线程并且不能修改为前台线程不能给入池的线程设置优先级或名称对于COM对象入池的所有线程都是多线程单元MTA线程许多COM对象都需要单线程单元STA 线程入池的线程只适合时间较短的任务如果线程需要长时间运行应使用Thread类创建线程或使用Task的LongRunning选项 3. Parallel类 Parallel和Task类都位于System.Threading.Task命名空间中是对Thread和ThreadPool类更高级的抽象。Parrallel类有For()、ForEach()、Invoke()三个方法前两者在每次迭代中调用相同的代码实现了数据并行性Invoke()允许同时调用不同的方法实现任务并行性。 For()和ForEach()两者的用法类似。如下例调用Parallel.For()方法实现从0到10的迭代每次迭代是并行执行的并且从输出结果可以看出执行顺序是不能保证的。 public static void Main(){ParallelLoopResult result Parallel.For(0, 10, i {Console.WriteLine(i:{0}, thread id: {1}, i, Thread.CurrentThread.ManagedThreadId);Thread.Sleep(10);});Console.WriteLine(Is completed: {0}, result.IsCompleted);//i: 0, thread id: 9//i: 2, thread id: 10//i: 1, thread id: 9//i: 3, thread id: 10//i: 4, thread id: 9//i: 6, thread id: 11//i: 7, thread id: 10//i: 5, thread id: 9//i: 8, thread id: 12//i: 9, thread id: 11//Is completed: TrueConsole.ReadKey();}通过ParallelLoopState的Break()或Stop()方法可以提前中断Parallel.For()的迭代。 public static void Main(){ParallelLoopResult result Parallel.For(0, 100, (i, state) {Console.WriteLine(i:{0}, thread id: {1}, i, Thread.CurrentThread.ManagedThreadId);if (i 10)state.Break();Thread.Sleep(10);});Console.WriteLine(Is completed: {0}, result.IsCompleted);Console.WriteLine(Lowest break iteration: {0}, result.LowestBreakIteration);//i: 0, thread id: 10//i: 25, thread id: 6//i: 1, thread id: 10//i: 2, thread id: 10//i: 3, thread id: 10//i: 4, thread id: 10//i: 5, thread id: 10//i: 6, thread id: 10//i: 7, thread id: 10//i: 8, thread id: 10//i: 9, thread id: 10//i: 10, thread id: 10//i: 11, thread id: 10//Is completed: False//Lowest break iteration: 11Console.ReadKey();}如需同时执行多个不同的任务可以使用Parallel.Invoke()方法它允许传递一个Action委托数组。 public static void Main(){Parallel.Invoke(Func1, Func2, Func3);Console.ReadKey();}4. Task类 相比于Thread类Task类为控制线程提供了更大的灵活性。Task类可以获取线程的返回值也可以定义连续的任务——在一个任务结束结束后开启下一个任务还可以在层次结构中安排任务在父任务中可以创建子任务这样就创建了一种依赖关系如果父任务被取消子任务也随之取消。Task类默认使用线程池中的线程如果该任务需长期运行应使用TaskCreationOptions.LongRunning属性告诉任务管理器创建一个新的线程而不是使用线程池中的线程。 启动任务 以下程序演示了几种通过Task类启动任务的方式 public class ThreadExample{public static void Main(){TaskFactory tf new TaskFactory();Task t1 tf.StartNew(TaskMethod.DoTask, using a task factory);Task t2 Task.Factory.StartNew(TaskMethod.DoTask, factory via a task);Task t3 new Task(TaskMethod.DoTask, using a task constructor and start);t3.Start();//需要.NetFramework 4.5以上var t4 Task.Run(() TaskMethod.DoTask(using Run method));Console.ReadKey();}class TaskMethod{static object taskLock new object();public static void DoTask(object msg){lock (taskLock){Console.WriteLine(msg);Console.WriteLine(Task id:{0}, Thread id :{1},Task.CurrentId null ? no task : Task.CurrentId.ToString(),Thread.CurrentThread.ManagedThreadId);}}}接收任务的返回值 对于任务有返回值的情况可使用Task泛型类TResult定义了返回值的类型以下代码演示了调用返回int值的任务的方法。 public static void Main(){var t5 new Taskint(TaskWithResult, Tuple.Createint, int(1, 2));t5.Start();t5.Wait();Console.WriteLine(adder results: {0}, t5.Result);Console.ReadKey(); }public static int TaskWithResult(object o){Tupleint, int adder (Tupleint, int)o;return adder.Item1 adder.Item2;}同步调用 调用Task类的RunSynchronously()方法可以实现同步调用直接在当前线程上调用该任务。 public static void Main(){TaskMethod.DoTask(Just Main thread);Task t1 new Task(TaskMethod.DoTask, using Run Sync);t1.RunSynchronously();//输出结果//Just Main thread//Task id: no task, Thread id: 9////using Run Sync//Task id:1, Thread id :9}指定连续任务 调用Task类的ContinueWith()方法可以指定连续的任务。 public static void Main(){TaskFactory tf new TaskFactory();Task t1 tf.StartNew((){Console.WriteLine(Current Task id {0}, Task.CurrentId);Console.WriteLine(执行任务1\r\n);Thread.Sleep(10);});Task t2 t1.ContinueWith((t) {Console.WriteLine(Last Task id {0}, t.Id);Console.WriteLine(Current Task id {0}, Task.CurrentId);Console.WriteLine(执行任务2\r\n);Thread.Sleep(10);});Task t3 t2.ContinueWith(delegate(Task t) {Console.WriteLine(Last Task id {0}, t.Id);Console.WriteLine(Current Task id {0}, Task.CurrentId);Console.WriteLine(执行任务3\r\n);}, TaskContinuationOptions.OnlyOnRanToCompletion);Console.ReadKey(); }//执行结果////Current Task id 1//执行任务1//Last Task id 1//Current Task id 2//执行任务2//Last Task id 2//Current Task id 3//执行任务3从执行结果可以看出任务123被顺序执行同时通过 TaskContinuationOptions 还可以指定何种情况下继续执行该任务常用的值包括OnlyOnFaulted, OnlyOnCanceled, NotOnFaulted, NotOnCanceled等。如将上例中的OnlyOnRanToCompletion改为OnlyOnFaulted任务2结束之后任务3将不被执行。 对于ContinueWith()的使用MSDN演示了更加优雅的“流式”调用方法 private void Button1_Click(object sender, EventArgs e) { var backgroundScheduler TaskScheduler.Default; var uiScheduler TaskScheduler.FromCurrentSynchronizationContext(); Task.Factory.StartNew(delegate { DoBackgroundComputation(); }, backgroundScheduler). ContinueWith(delegate { UpdateUI(); }, uiScheduler). ContinueWith(delegate { DoAnotherBackgroundComputation(); }, backgroundScheduler). ContinueWith(delegate { UpdateUIAgain(); }, uiScheduler); } 任务的层次结构 如果在一个Task内部创建了另一个任务这两者间就存在父/子的层次结构当父任务被取消时子任务也会被取消。如果不希望使用该层次结构可在创建子任务时选择TaskCreationOptions.DetachedFromParent。 5. BackgroundWorker控件 除了上述四类直接操作多线程的方法C#还提供了BackgroundWorker控件帮助用户更简单、安全地实现多线程运算。该控件提供了DoWork, ProgressChanged 和 RunWorkerCompleted事件为DoWork添加事件处理函数再调用RunWorkerAsync()方法即可创建一个新的线程执行DoWork任务。ProgressChanged和RunWorkerCompleted事件均在UI线程中执行添加相应的处理函数即可完成任务线程与UI线程间的交互可用于显示任务的执行状态完成百分比、执行结果等。同时该控件还提供了CancleAsync()方法以中断线程的执行需注意的是调用该方法后只是将控件的CancellationPending属性置True用户需在程序执行过程中查询该属性以判定是否应中断线程。
http://www.hkea.cn/news/14322264/

相关文章:

  • 免费网站建设能做吗筑招网
  • 国外免费素材模板网站用几个域名做网站好
  • 做名人故居的网站多少钱东莞市优速网络科技有限公司
  • 东莞寮步网站建设wordpress安装在windows上
  • 抚州市建设局官网站什么是网络科技公司
  • 建设网站包括哪些网站建设:中企动力
  • 网站推广策划书怎么说三星网上商城退款很慢
  • 公司网站建设行业怎么样wordpress博客文章栏目
  • 给公司做网站要多少钱网站运营包括哪些
  • 重庆快速网站推广上海企业建站流程
  • 网站排名快速提升工具怎么做网站规划
  • 金华网站建设公司h5响应式的网站
  • 哪一个做h5的网站好公司网站开发交接注意事项
  • 网站搭建一般要自己做的网站百度搜不到
  • 深圳互动网站建设安徽省交通运输厅门户网站
  • 贸易公司网站源码长春建设网站公司吗
  • 中国做陶壶的网站有哪些wordpress 新文章后显示
  • 宁波企业网站搭建价格网上开店的流程是什么
  • 贵阳网站建设价格金光华网站建设
  • 文明网站建设方案及管理制度国际贸易英文网站
  • 网站解析怎么设置十大求职招聘app排行
  • 网站需要每个城市做推广吗郑州汉狮哪家做网站好
  • 提高网站建设管理水平怎样看网站是什么语言做的
  • 基于ASP与Access数据库的网站开发wordpress页面设计
  • 网站后台 登录界面模板 远吗江苏网站设计
  • 制作企业网站素材视频网站空间商排名
  • 哪些动物可以做网站名设计不错的网站
  • 网站系统建设需要什么资质女生学市场营销好吗
  • 你的网站正在建设中互动营销策略
  • 惠安县住房和城乡建设局网站深圳住房和建设管理局官方网站