網站首頁 編程語言 正文
Parallel類是對線程的一個抽象。該類位于System.Threading.Tasks名稱空間中,提供了數據和任務并行性。
Paraller類定義了數據并行地For和ForEach的靜態方法,以及任務并行的Invoke的靜態方法。Parallel.For()和Parallel.ForEach()方法在每次迭代中調用相同的代碼,Paraller.Invoke()允許調用不同的方法。
1.Parallel.For
Parallel.For()方法類似C#語法的for循環語句,多次執行一個任務。但該方法并行運行迭代,迭代的順序沒有定義。
Parallel.For()方法中,前兩個參數定義了循環的開頭和結束,第三個參數是一個Action委托。Parallel.For方法返回類型是ParallelLoopResult結構,它提供了循環是否結束的信息。
Parallel.For有多個重載版本和多個泛型重載版本。
示例:
static void ForTest()
{
ParallelLoopResult plr =
Parallel.For(0,10,i => {
Console.WriteLine("{0},task:{1},thread:{2}",i,Task.CurrentId,Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
});
if (plr.IsCompleted)
Console.WriteLine("completed!");
}
輸出:
任務不一定映射到一個線程上。線程也可以被不同的任務重用。
上面的例子,使用了.NET 4.5中新增的Thread.Sleep方法,而不是Task.Delay方法。Task.Delay是一個異步(http://www.cnblogs.com/afei-24/p/6757361.html)方法,用于釋放線程供其它任務使用。
示例:
static void ForTestDelay()
{
ParallelLoopResult plr =
Parallel.For(0, 10,async i => {
Console.WriteLine("{0},task:{1},thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
Console.WriteLine("{0},task:{1},thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
});
if (plr.IsCompleted)
Console.WriteLine("completed!");
Console.ReadKey();
}
輸出:
上面代碼使用了await關鍵字進行延遲,輸出結果顯示延遲前后的代碼運行在不同的線程中。而且延遲后的任務不再存在,只留下線程,這里還重用了前面的線程。另一個重要的方面是,Parallel類的For方法并沒有等待延遲,而是直接完成。parallel類只等待它創建的任務,而不等待其它后臺活動。所以上面代碼使用了Console.ReadKey();使主線程一直運行,不然很可能看不到后面的輸出。
2.提前停止Parallel.For
For()方法的一個重載版本接受第三個Action<int,ParallelLoopState>委托類型的參數。使用這個方法可以調用ParallelLoopState的Break()或Stop()方法,以停止循環。
注意,前面說到,迭代的順序是沒有定義的。
示例:
static void ForStop()
{
ParallelLoopResult plr =
Parallel.For(0,10,(int i,ParallelLoopState pls)=> {
Console.WriteLine("{0},task:{1},thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
if (i > 5)
pls.Break();
});
Console.WriteLine("is completed:{0}",plr.IsCompleted);
Console.WriteLine("最低停止索引:{0}",plr.LowestBreakIteration);
}
輸出:
迭代值在大于5時中斷,但其它已開始的任務同時執行。
3.對Parallel.For中的每個線程初始化
Parallel.For方法使用多個線程來執行循環,如果需要對每個線程進行初始化,就可以使用Parallel.For<TLocal>()方法。除了from和to對應的值之外,Parallel.For方法的泛型版本還接受3個委托參數:
第一個委托參數的類型是Func<TLocal>,這個方法僅對用于執行迭代的每個線程調用每一次。
第二個委托參數為循環體定義了委托。該參數類型是Func<int, ParallelLoopState, TLocal, TLocal>。其中第一個參數是循環迭代,第二個參數ParallelLoopState允許停止循環,第三個參數接受從上面參數委托Func<TLocal>返回的值,該委托還需返回一個TLocal類型的值。該方法對每次迭代調用。
第三個委托參數指定一個委托Action<TLocal>,接受第二個委托參數的返回值。這個方法僅對用于執行迭代的每個線程調用每一次。
示例:
static void ForInit()
{
ParallelLoopResult plr =
Parallel.For(0,10,()=> {
Console.WriteLine("init thread:{0},task:{1}",Thread.CurrentThread.ManagedThreadId,Task.CurrentId);
return Thread.CurrentThread.ManagedThreadId.ToString();
},
(i, pls,strInit)=> {
Console.WriteLine("body:{0},strInit:{1},thraed:{2},task:{3}",i,strInit,Thread.CurrentThread.ManagedThreadId,Task.CurrentId);
return i.ToString();
},
(strI)=> {
Console.WriteLine("finally {0}",strI);
});
}
輸出:
4.Parallel.ForEach
Parallel.ForEach方法遍歷實現了IEnumerable的集合,類似于foreach,但以異步方式遍歷。沒有確定遍歷順序。
示例:
static void ForeachTest()
{
string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve" };
ParallelLoopResult plr = Parallel.ForEach<string>(data, s =>
{
Console.WriteLine(s);
});
if (plr.IsCompleted)
Console.WriteLine("completed!");
}
如果需要中斷,可以使用ForEach的重載版本和參數ParallelLoopState。
訪問索引器:
ParallelLoopResult plr1 = Parallel.ForEach<string>(data, (s,pls,l) =>
{
Console.WriteLine("data:{0},index:{1}",s,l);
});
5.Parallel.Invoke
如果多個任務并行運行,可以使用Parallel.Invoke方法。該方法允許傳遞一個Action委托數組。
static void ParallerInvoke()
{
Action[] funs = { Fun1,Fun2};
Parallel.Invoke(funs);
}
static void Fun1()
{
Console.WriteLine("f1");
Console.WriteLine("task:{0},thread:{1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
}
static void Fun2()
{
Console.WriteLine("f2");
Console.WriteLine("task:{0},thread:{1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
}
原文鏈接:https://www.cnblogs.com/afei-24/p/6904179.html
相關推薦
- 2022-06-01 Python學習之內置函數總結_python
- 2022-05-29 C#實現文本轉語音功能_C#教程
- 2022-12-01 C語言數據在內存中的存儲流程深入分析_C 語言
- 2022-11-18 詳解C語言內核字符串拷貝與比較_C 語言
- 2022-10-17 Go使用select切換協程入門詳解_Golang
- 2023-01-05 Kotlin注解與反射的定義及創建使用詳解_Android
- 2022-09-10 Go語言的反射機制詳解_Golang
- 2022-05-20 Windows10或者11 使用Administrator登錄
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支