标签:
? 创建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方法即可终止迭代
和普通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 });
标签:
原文地址:http://www.cnblogs.com/yetsen/p/4272347.html