线程--线程池--委托--task---async/await

如标题,这是.net发展异步的一个路线

记录下备忘起来

 线程(Thread)

 Thread thread = new Thread(new ThreadStart(Method));//threadStart创建多线程(无参数)---〉 thread.Start();//执行

Thread thread = new Thread(new ParameterizedThreadStart(Method)); //ParameterizedThreadStart 帮顶有参数的异步方法----〉thread.Start(参数)

Thread有一个属性IsBackground,通过把此属性设置为true,就可以把线程设置为后台线程,thread.start方法启动默认是前台线程。

Thread.Abort()终止线程并引发 ThreadAbortException异常,Thread.ResetAbort()方法取消终止,继续执行。

 线程池(ThreadPool)

 分工作者线程和I/O线程

ThreadPool线程池中包含有两个静态方法可以直接启动工作者线程:
一为 ThreadPool.QueueUserWorkItem(WaitCallback)
二为 ThreadPool.QueueUserWorkItem(WaitCallback,Object) 

先把WaitCallback委托指向一个带有Object参数的无返回值方法,再使用 ThreadPool.QueueUserWorkItem(WaitCallback) 就可以异步启动此方法,此时异步方法的参数被视为null 。 object对象作为参数传送到回调函数中

 委托是最灵活的工作者线程,见委托时间介绍

 task(基于任务的编程模型,简化了异步开发,比线程性能优越,任务调用了更低限度的线程池,可以替代老旧thread,但它同工作者线程池一样不适合运行较长时间的任务,如果需要的话则使用任务工厂的longrunning选项,即可告诉任务调度一个新的线程,类似直接new thread不鸟线程池)

 //第一种方式开启,created状态,任务在这个状态时才能使用start()方法让任务进入排队运行,就是第二种方式。

2          var task1 =  new Task(() =>
3         {
4             Run1();
5         });


// 第二种方式开启,直接跳过第一步created状态,进入等待运行状态
var task2 = Task.Factory.StartNew(() =>
2             {
3                 Run2();
4             });

 

  Task.WaitAll(task1, task2);//并行执行

取消标记”叫做CancellationTokenSource.Token,在创建task的时候传入此参数,就可以将主线程和任务相 关联,然后在任务中设置“取消信号“叫做ThrowIfCancellationRequested来等待主线程使用Cancel来通知,一旦cancel被调用。task将会 抛出OperationCanceledException来中断此任务的执行,最后将当前task的Status的IsCanceled属性设为true。

获取返回值 

 这里t1任务执行完毕后,使用continuewith开始第二个任务(回调另一个方法),因为task并没有提供回调事件。

// 获取返回值第一种task<T>
var t1 = Task.Factory.StartNew<List< string>>(() => {  return Run1(); });
t1.Wait();t1.result

// 获取返回值第二种
var t1 = Task.Factory.StartNew<List< string>>(() => {  return Run1(); });

         var t2 = t1. ContinueWith((i) =>  // Continuewith 串行执行,waitall并行执行
         {
             Console.WriteLine( " t1集合中返回的个数: " +  string.Join( " , ", i.Result));
         });

 

 

async/await (简化异步操作,不需要回掉函数而是用顺序编程)

 // Signature specifies Task<TResult>

async Task< int> TaskOfTResult_MethodAsync()
{
     int hours;
     //  . . .
    
//  Return statement specifies an integer result.
     return hours;
}

//  Calls to TaskOfTResult_MethodAsync
Task< int> returnedTaskTResult = TaskOfTResult_MethodAsync();
int intResult = await returnedTaskTResult;
//  or, in a single statement
int intResult = await TaskOfTResult_MethodAsync();


//  Signature specifies Task
async Task Task_MethodAsync()
{
     //  . . .
    
//  The method has no return statement.  
}

//  Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync();
await returnedTask;
//  or, in a single statement
await Task_MethodAsync();

任务工厂 static void Main(string[] args        {

            CancellationTokenSource cts = new CancellationTokenSource();
            //cts可以共享给任务工厂,同时取消一组任务
            TaskFactory taskFactory = new TaskFactory();
            Task[] tasks = new Task[]
                {
                    taskFactory.StartNew(() => Add(cts.Token)),
                    taskFactory.StartNew(() => Add(cts.Token)),
                    taskFactory.StartNew(() => Add(cts.Token))
                };
            //CancellationToken.None指示TasksEnded回调不能被取消
            taskFactory.ContinueWhenAll(tasks, TasksEnded, CancellationToken.None);
            Console.ReadKey();//等待按键取消任务
            cts.Cancel();
            Console.ReadKey();
        }
        
        static void TasksEnded(Task[] tasks)
        {
            Console.WriteLine("所有任务已完成!");
        }

 static int Add(CancellationToken ct) { Console.WriteLine("任务开始……");
int result =0;
while (!ct.IsCancellationRequested) { result++; Thread.Sleep(1000); } return result; } 

下面是父子任务模式

using System;
using System.Threading;
using System.Threading.Tasks;
public class Program {
    private static Int32 Sum(Int32 n)
    {
        Int32 sum = 0;
        for (; n > 0; n--)
        checked { sum += n; } 
        return sum;
    }

    public static void Main() {

        Task<int32[]> parent = new Task<int32[]>(() => {
            var results = new Int32[3];   // 创建一个数组存储结果

            // 创建三个子任务,并进入执行状态
            new Task(() => results[0] = Sum(100), 
                TaskCreationOptions.AttachedToParent).Start();
            new Task(() => results[1] = Sum(200), 
                TaskCreationOptions.AttachedToParent).Start();
            new Task(() => results[2] = Sum(300), 
                TaskCreationOptions.AttachedToParent).Start();

            // 返回结果集
            return results;
        });

        //当父子任务都执行完毕后,显示结果。这句比较重要,为parent增加了回掉,对parent的结果parentTask.Result==results进行循环显示
        var cwt = parent.ContinueWith(parentTask => 
                            Array.ForEach(parentTask.Result, Console.WriteLine));

        // 开始父任务,子任务将会执行
        parent.Start();

        cwt.Wait(); // 测试等待回掉效果
    }
}

 

转载于:https://www.cnblogs.com/zfcflower/archive/2012/11/29/2794021.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值