【C# Parallel】开端
阅读原文时间:2023年07月13日阅读:3

1、必须熟练掌握锁、死锁、task的知识,他是建立这两个的基础上的。task建立在线程和线程池上的。

2、并不是所有代码都适合并行化。 例如,如果某个循环在每次迭代时只执行少量工作,或它在很多次迭代时都不运行,那么并行化的开销可能导致代码运行更慢。

3、 Parallel.For()和Paraller.ForEach()方法在每次迭代中调用相同的代码,都有返回值ParallelLoopResult 。而Parallel.Invoke()方法允许同时调用不同的方法,返回值viod。

4、 ForEach的格式【Item、否是带有并行选项、【Item 、否是有循环状态、否是有索引 、否是有线程本地变量 】】

For的格式【起始索(引包含),结束索引(不包含),是否有并行选项【起始索引,释放有循环状态,否是有线程本地变量】】

1、C#通过Parallel类提供并行任务支持,可以很简单的使用线程池

2、要注意的是,Parallel不保障执行顺序

相关的类:

Parallel
ParallelLoopResult
ParallelLoopState
ParallelOptions

For的格式【起始索(引包含),结束索引(不包含),释放有并行选项【起始索引,释放有循环状态,是否线程本地变量】】

用法一、For(Int32, Int32, Action)

int[] count = Enumerable.Range(1, 100).ToArray();
Parallel.For(1, count.Length, indexer => { Console.WriteLine(indexer); });

用法二、For(Int32, Int32, Action)

ParallelOptions op = new() { CancellationToken = CancellationToken.None };
Parallel.For(1, 2, (indexer, op) => { Console.WriteLine(indexer); });

用法三、For(Int32, Int32, ParallelOptions, Action)

ParallelOptions op = new() { CancellationToken = CancellationToken.None };
op.TaskScheduler = TaskScheduler.Default;
op.MaxDegreeOfParallelism = 1;
Parallel.For(1, 2, op, indexer => { Console.WriteLine(indexer); });

用法四、

编写具有线程局部变量的 Parallel.For 循环

public static ParallelLoopResult For
(
int fromInclusive, //范围下线 包含
int toExclusive, //范围上线 不包含
Func localInit,//TLocal表示线程本地变量的类型
FuncParallelLoopState, TLocal, TLocal> body,//TLocal表示线程本地变量的类型
Action localFinally
)

案例:

//TLocal 线程本地 变量的类型
int totalSum = 0;
Parallel.For(1, 10,
()=> "开始打印",// "开始打印" 被保存到线程本地变量中
(indexer,loopState, LocalValue) =>
{
Console.WriteLine(LocalValue +" Thread "+ indexer );
return LocalValue += indexer; // LocalValue += indexer被保存到线程本地变量中
},

LocalValue => Console.WriteLine("结束打印")  
);  

/*
输出
开始打印 Thread 1
开始打印 Thread 2
开始打印2 Thread 8 return LocalValue += indexer;被存储到本地线程变量中LocalValue,
开始打印28 Thread 9 所以打印出 开始打印28
开始打印 Thread 6
开始打印 Thread 5
结束打印
开始打印1 Thread 7
结束打印
开始打印 Thread 3
结束打印
结束打印
开始打印 Thread 4
结束打印
结束打印*/

Enumerable和 Partitioner 都是以下格式

ForEach(IEnumerable, ParallelOptions, Action)
ForEach(IEnumerable, ParallelOptions, Action)

ForEach(IEnumerable, Action)
ForEach(IEnumerable, Action)
ForEach(IEnumerable, Action)
ForEach(IEnumerable, ParallelOptions, Action)

ForEach(IEnumerable, Func, Func, Action)
ForEach(IEnumerable,
Func,
Func,
Action)
ForEach(IEnumerable,
ParallelOptions, Func,
Func,
Action)
ForEach(IEnumerable,
ParallelOptions, Func,
Func,
Action)

用法一:Item

ForEach(IEnumerable, Action)案例如下:

string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
Parallel.ForEach(data, item => { Console.WriteLine(item); });

用法二:Item 、循环状态、带索引

ForEach(IEnumerable, Action)案例如下:

string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
Parallel.ForEach(data, (item,loopstate,indexer )=>
{
if(item == "three")
{

    loopstate.Break();  
    Console.WriteLine($"item:{item} index:{indexer} ShouldExitCurrentIteration:{loopstate.ShouldExitCurrentIteration} LowestBreakIteration(索引):{loopstate.LowestBreakIteration}");  
}  
Console.WriteLine($"item:{item} index:{indexer}"  );  

});

用法三:Item、带有并行选项、循环状态、索引

ForEach(IEnumerable, ParallelOptions, Action)案例如下:

string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
ParallelOptions op = new();
op.TaskScheduler = TaskScheduler.Default;//默认的任务调度器
op.MaxDegreeOfParallelism = 5;//并行度
op.CancellationToken=CancellationToken.None;//禁止取消
Parallel.ForEach(data, op, (item,loopstate,indexer )=>
{
if(item == "zero")
{

    loopstate.Break();  
    Console.WriteLine($"item:{item} index:{indexer} ShouldExitCurrentIteration:{loopstate.ShouldExitCurrentIteration} LowestBreakIteration:{loopstate.LowestBreakIteration}");  
}  
Console.WriteLine($"item:{item} index:{indexer}"  );  

});

用法四:Item、带有并行选项、循环状态、 线程本地变量

ForEach(IEnumerable, ParallelOptions, Func, Func, Action)案例如下:

string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
ParallelOptions op = new();
op.TaskScheduler = TaskScheduler.Default;//默认的任务调度器
op.MaxDegreeOfParallelism = 5;//并行度
op.CancellationToken=CancellationToken.None;//禁止取消
//自行推断TSource,TLocal
Parallel.ForEach(data, op,
()=>"开始输出:",//初始化线程本地变量

(item,loopstate,  TLocal) =>  

{
if(item == "zero")
{

    loopstate.Break();  
    Console.WriteLine($"item:{item} index:{TLocal} ShouldExitCurrentIteration:{loopstate.ShouldExitCurrentIteration} LowestBreakIteration:{loopstate.LowestBreakIteration}");  
    return TLocal+ "=>Break";  
}  
Console.WriteLine($"item:{item} index:{TLocal}"  );  
return TLocal + "=>complete";  

},
local => Console.WriteLine(local) //输出线程本地变量

);

用法五:Item、带有并行选项、循环状态、索引、 线程本地变量

ForEach(IEnumerable, ParallelOptions, Func, Func, Action)

string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
ParallelOptions op = new();
op.TaskScheduler = TaskScheduler.Default;//默认的任务调度器
op.MaxDegreeOfParallelism = 5;//并行度
op.CancellationToken=CancellationToken.None;//禁止取消
//自行推断TSource,TLocal
Parallel.ForEach(data, op,
()=>"开始输出:",//初始化线程本地变量

(item,loopstate, index, TLocal) =>  

{
if(item == "zero")
{

    loopstate.Break();  
    Console.WriteLine($"item:{item} index:{TLocal} ShouldExitCurrentIteration:{loopstate.ShouldExitCurrentIteration} LowestBreakIteration:{loopstate.LowestBreakIteration}");  
    return TLocal+ "=>Break";  
}  
Console.WriteLine($"item:{item} index:{TLocal}"  );  
return TLocal + "=>complete";  

},
local => Console.WriteLine(local) //输出线程本地变量

);

用法六:Item 、循环状态、 线程本地变量

ForEach(IEnumerable, Func, Func, Action)案例如下:

string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };

//自行推断TSource,TLocal
Parallel.ForEach(data,
()=>"开始输出:",//初始化线程本地变量

(item,loopstate,  TLocal) =>  

{
if(item == "zero")
{

    loopstate.Break();  
    Console.WriteLine($"item:{item} index:{TLocal} ShouldExitCurrentIteration:{loopstate.ShouldExitCurrentIteration} LowestBreakIteration:{loopstate.LowestBreakIteration}");  
    return TLocal+ "=>Break";  
}  
Console.WriteLine($"item:{item} index:{TLocal}"  );  
return TLocal + "=>complete";  

},
local => Console.WriteLine(local) //输出线程本地变量

);

用法七:Item 、循环状态、索引、 线程本地变量

ForEach(IEnumerable, Func, Func, Action)

string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };

//自行推断TSource,TLocal
Parallel.ForEach(data,
()=>"开始输出:",//初始化线程本地变量

(item,loopstate,  TLocal,index) =>  

{
if(item == "zero")
{

    loopstate.Break();  
    Console.WriteLine($"item:{item} index:{TLocal} ShouldExitCurrentIteration:{loopstate.ShouldExitCurrentIteration} LowestBreakIteration:{loopstate.LowestBreakIteration}");  
    return TLocal+ "=>Break";  
}  
Console.WriteLine($"item:{item} index:{TLocal}"  );  
return TLocal + "=>complete";  

},
local => Console.WriteLine(local) //输出线程本地变量

);

Invoke(Action[])  :尽可能并行执行提供的每个操作。 返回值Viod

Parallel.Invoke(
() => Console.WriteLine("sfsfsdfsdf1"),
() => Console.WriteLine("sfsfsdfsdf2"),
() => Console.WriteLine("sfsfsdfsdf3")
);

Invoke(ParallelOptions, Action[]) :执行所提供的每个操作,而且尽可能并行运行,除非用户取消了操作。返回值Viod

ParallelOptions op = new();
op.TaskScheduler = TaskScheduler.Default;//默认的任务调度器
op.MaxDegreeOfParallelism = 5;//并行度
op.CancellationToken = CancellationToken.None;//禁止取消
Parallel.Invoke(
() => Console.WriteLine("sfsfsdfsdf1"),
() => Console.WriteLine("sfsfsdfsdf2"),
() => Console.WriteLine("sfsfsdfsdf3")
);

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章