码迷,mamicode.com
首页 > 其他好文 > 详细

TPL

时间:2015-02-04 15:58:28      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

  • 任務

?    创建Task
传递Action委托给Task的构造函数即可,如果需要附加参数,使用Action<T>委托

private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var obj = new object();
            var task = new Task(DoSth, obj);
        }

        void DoSth(object obj)
        {

        }

默认Task会以并行方式运行,可以使用ContinueWith来实现顺序执行


?    控制Task
TaskFactory的构造器可以指定TaskCreationOptions、TaskScheduler、TaskContinuationOptions,用来给批量任务设定统一的行为

public TaskFactory(
    CancellationToken cancellationToken,
    TaskCreationOptions creationOptions,
    TaskContinuationOptions continuationOptions,
    TaskScheduler scheduler
)


?    取消Task
定义CancellationToken字段,传人到Task中,然后在任务体中检查Token是否取消

private CancellationTokenSource _tokenSource = new CancellationTokenSource();

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var task = new Task(DoSth, _tokenSource.Token);
            task.Start();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _tokenSource.Cancel();
        }

        void DoSth()
        {
            if (_tokenSource.IsCancellationRequested)
            {
                
            }
        }

還可以使用Register給token傳遞一個回調方法,當任務取消后運行該方法

var task = new Task(DoSth, _tokenSource.Token);
            _tokenSource.Token.Register(DoAfterCancel);


?    同步Task
Wait、WaitAll、WaitAny可以用来等待任务完成
?    获取Task结果
Task的Result属性用来输出结果,它会阻塞直至任务完成
?    处理异常
AggregateException用来集中处理多个Task产生的异常,其方法Handle需要一个Func<Exception,bool>委托,即对每一个Task的异常调用该委托,返回值表示该Task是否处理了异常

try
            {
                Task t1 = Task.Run((Action)DoSth);
                Task t2 = Task.Run((Action)DoSth);
                Task t3 = Task.Run((Action)DoSth);
            }
            catch (AggregateException ex)
            {
                ex.Handle(HandleException);
            }

        bool HandleException(Exception ex)
        {
            if (ex is TaskCanceledException)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

 

  • 并行

Task的同步不太方便,Parallel就是用来简化同步操作的,它在内部使用一组Task并自动同步

取消Parallel

传入ParallelLoopState参数给任务方法,调用LoopState的Stop方法即可终止迭代

 

  • PLINQ

和普通LINQ不同,Plinq是可以取消的,給WithCancellation方法传入一个CancellationToken即可

 

  • 同步

基本思路就是上鎖,方式有多種,但所有的同步技術都支持CancellationToken

ManualResetEventSlim

該對象有兩種狀態,有信號和無信號,無信號時Wait方法會阻塞,此時等待的綫程會自旋一定的次數然後才挂起

調用Set方法會設置爲有信號狀態,所有等待的綫程會恢復執行

Task.Run(delegate
            {
                DoSth();
                _resetEvent.Set();
            });

            Task.Run(delegate {
                _resetEvent.Wait();
                Goon();
            });

SemaphoreSlim

信號燈的特色在於可以控制同步對象的數量,每次調用Wait方法,都會試圖減少信號燈的數量,衹要該數量大於0,綫程就繼續執行,反之就會阻塞直至有可用的信號燈;調用Release則會增加信號燈的數量。

SemaphoreSlim _sema = new SemaphoreSlim(3);

            Task.Run(delegate
            {
                _sema.Wait();
                // do something here
                _sema.Release();
            });
            
            Task.Run(delegate
            {
                _sema.Wait();
                // do something here
                _sema.Release();
            });

            Task.Run(delegate
            {
                //這個task會阻塞,直到前兩個task調用Release
                _sema.Wait();
                // do something here
                _sema.Release();
            });

CountdownEvent

該類的行爲和信號燈正好相反,當數量大於0的時候阻塞,等於0的時候恢復執行

Wait方法用來阻塞,Signal方法用來遞減計數器

ReaderWriterLock

爲讀寫資源提供同步支持,允許多個讀取器,但讀和寫不能同時進行,是互斥的

Barrier

用來同步一組任務,它會暫停一部分已先到達同步點的任務,以等待組内其它任務到達同步點

SignalAndWait用來遞減未到達任務數,當其爲0時所有任務才能繼續執行

還可以給Barrier指定一個委托,當到達同步點后就回調該委托

Barrier _bar = new Barrier(3);

            Task.Run(delegate
            {
                // do something here
                _bar.SignalAndWait();
                // continue doing something
            });
            
            Task.Run(delegate
            {
                // do something here
                _bar.SignalAndWait();
                // continue doing something
            });

            Task.Run(delegate
            {
                // do something here
                _bar.SignalAndWait();
                // continue doing something
            });

TPL

标签:

原文地址:http://www.cnblogs.com/yetsen/p/4272347.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!