C# Task TaskFactory 異步線程/異步任務


Task是.NetFramework3.0出現的,線程是基於線程池,然后提供了豐富的API

TaskFactory  提供對創建和計划 Task 對象的支持

創建和啟動異步任務

1、Task task = new Task(() => ThreadPoolHelper.DoSomeThing());
      task.Start();

2、Task task = Task.Run(() => ThreadPoolHelper.DoSomeThing());

3、TaskFactory taskFactory = Task.Factory;

      Task task = taskFactory.StartNew(() => ThreadPoolHelper.DoSomeThing());

Task的線程是源於線程池 ,假如說我想控制下Task的並發數量,該怎么做?

 1             {
 2                 //ThreadPool.SetMaxThreads(8, 8);
 3                 //線程池是單例的,全局唯一的
 4                 //設置后,同時並發的Task只有8個;而且線程是復用的;
 5                 //全局的,請不要這樣設置!!!
 6                 for (int i = 0; i < 100; i++)
 7                 {
 8                     int k = i;
 9                     Task.Run(() =>
10                     {
11                         Console.WriteLine($"This is k={k},i={i} running ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("00")}");
12                         Thread.Sleep(2000);
13                     });
14                 }
15             }
View Code

運行上面的代碼我們發現幾個需要注意的地方:

1、i的值等於100,因為異步線程的啟動並不阻塞主線程;

2、使用ThreadPool.SetMaxThreads 方法 設置后,雖然能達到效果,但是線程池是單例的,全局唯一的,這樣設置會影響整個程序;

那么如何實現?

 1             {
 2                 List<Task> taskList = new List<Task>();
 3                 for (int i = 0; i < 10000; i++)
 4                 {
 5                     int k = i;
 6                     if (taskList.Count(t => t.Status != TaskStatus.RanToCompletion) >= 20)
 7                     {
 8                         Task.WaitAny(taskList.ToArray());
 9                         taskList = taskList.Where(t => t.Status != TaskStatus.RanToCompletion).ToList();
10                     }
11                     taskList.Add(Task.Run(() =>
12                     {
13                         Console.WriteLine($"This is {k} running ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("00")}");
14                         Thread.Sleep(2000);
15                     }));
16                 }
17             }
View Code

使用Parallel也可以實現

Task常用方法

1、Delay(Int32)、Delay(Int32, CancellationToken)、Delay(TimeSpan)、Delay(TimeSpan, CancellationToken)

在指定的時間后執行任務

1             {
2                 Stopwatch stopwatch = new Stopwatch();
3                 stopwatch.Start();
4                 Console.WriteLine("在Delay之前");
5                 Task.Delay(2000).ContinueWith(t => { Console.WriteLine($"Delay耗時ContinueWith Start{stopwatch.ElapsedMilliseconds}"); ThreadPoolHelper.DoSomeThing(); Console.WriteLine($"Delay耗時ContinueWith End{stopwatch.ElapsedMilliseconds}"); });
6                 Console.WriteLine($"Delay耗時{stopwatch.ElapsedMilliseconds}");
7             }
View Code

2、ContinueWith(Action<Task,Object>, Object)、ContinueWith(Action<Task>)、ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler)、...

目標任務完成后異步執行一個延續任務

3、Wait()、Wait(CancellationToken)、Wait(Int32)、Wait(Int32, CancellationToken)、Wait(TimeSpan)

等待任務或經過指定時間為止  與Thread.Join方法、waitHandle.WaitOne方法 作用相當

4、WaitAll(Task[])、WaitAll(Task[], CancellationToken)、WaitAll(Task[], Int32)、WaitAll(Task[], Int32, CancellationToken)、WaitAll(Task[], TimeSpan)

等待所有任務對象完成執行或經過指定時間為止,或等到取消等待

5、WaitAny(Task[])、WaitAny(Task[], CancellationToken)、WaitAny(Task[], Int32)、WaitAny(Task[], Int32, CancellationToken)、WaitAny(Task[], TimeSpan)

等待所有任務對象任何一個任務對象完成執行或經過指定時間為止,或等到取消標記取消

6、WhenAll(IEnumerable<Task>)、WhenAll(Task[])、WhenAll<TResult>(IEnumerable<Task<TResult>>)、WhenAll<TResult>(Task<TResult>[])

所有任務對象都已完成時,創建一個新的任務並執行

7、WhenAny(IEnumerable<Task>)、WhenAny(Task[])、WhenAny<TResult>(IEnumerable<Task<TResult>>)、WhenAny<TResult>(Task<TResult>[])

所有任務對象任何一個任務完成就創建一個新的任務並執行

TaskFactory常用方法

1、ContinueWhenAll(Task[], Action<Task[]>)、ContinueWhenAll(Task[], Action<Task[]>, CancellationToken)、ContinueWhenAll(Task[], Action<Task[]>, CancellationToken, TaskContinuationOptions, TaskScheduler)、...

所有任務對象都已完成時,創建一個新的任務並執行   與Task.WhenAll方法 作用相當

2、ContinueWhenAny(Task[], Action<Task>)、ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[], Action<Task<TAntecedentResult>>)、...

所有任務對象任何一個任務完成就創建一個新的任務並執行 與Task.WhenAny方法 作用相當

微軟文檔:

Task:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.task?view=netframework-4.8

TaskFactory:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.taskfactory?view=netframework-4.8


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM