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

类似于众人帮的做任务赚佣金网站友妙招链接

类似于众人帮的做任务赚佣金网站,友妙招链接,昌吉住房和城乡建设局网站,政府网站建设哪家好C#多线程(补充) 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 Task<int>(TaskWithResult, Tuple.Create<int, int>(1, 2));t5.Start();t5.Wait();Console.WriteLine("adder results: {0}", t5.Result);Console.ReadKey(); }public static int TaskWithResult(object o){Tuple<int, int> adder = (Tuple<int, 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

从执行结果可以看出,任务1,2,3被顺序执行,同时通过 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/29984/

相关文章:

  • 昭通网站制作aso优化技巧
  • 制作网站时怎样做滚动字幕新网站多久会被百度收录
  • 余姚物流做网站微信指数是搜索量吗
  • 怎样做网站轮播今日国内重大新闻事件
  • 想给大学做网站百度网盘搜索神器
  • jsp网站开发论文官方app下载安装
  • 关于机场建设的网站今日疫情最新情况
  • 网站域名注册服务商google浏览器官方
  • 通过网站开发工具怎么改自动跳网站百度指数有哪些功能
  • 可以发锚文本的网站百度搜索官方网站
  • 东莞网站建设企慕简述如何优化网站的方法
  • 可以做网站的公司seo外包
  • 自己怎么做网站视频赚钱5g网络优化培训
  • 数据库修改网站管理员密码seo网站有优化培训吗
  • 福田做商城网站建设找哪家公司好抖音怎么运营和引流
  • 厘米售卡站怎么做网站禁止搜索引擎收录的方法
  • 网站首页滚动图片怎么做谷歌搜索关键词排名
  • 嵩县网站开发友情链接获取的途径有哪些
  • 国家企业信息公示网(广东)海南快速seo排名优化
  • 高端网站设计 上海徐州seo排名公司
  • 泰安网站建设公司排名石家庄最新消息
  • 域名只做邮箱没网站要备案吗常见的网络推广方式包括
  • 昆山建设局网站360搜索首页
  • 正常做网站多少钱无锡网站制作无锡做网站
  • php做网站csdn网站seo公司哪家好
  • 今日头条建站工具何鹏seo
  • wordpress 培训模板优化落实疫情防控新十条
  • 关于做外汇现货的网站太原整站优化排名外包
  • 星悦做任务网站是新网站百度收录
  • 十大营销网站seo关键词查询工具