C# 如何按顺序执行Parallel.For循环和Parallel.ForEach循环
我知道如何编写C# 如何按顺序执行Parallel.For循环和Parallel.ForEach循环,c#,task-parallel-library,C#,Task Parallel Library,我知道如何编写Parallel.For和Parallel.ForEach循环。以下是这两种方法的示例代码: Parallel.For(0,10, (int i) = > { Console.Writeline(i); }); Parallel.ForEach(fruits, fruit => { Console.WriteLine("Fruit Name: {0}, Thread Id= {1}", fruit, Thread.CurrentThr
Parallel.For
和Parallel.ForEach
循环。以下是这两种方法的示例代码:
Parallel.For(0,10, (int i) = >
{
Console.Writeline(i);
});
Parallel.ForEach(fruits, fruit =>
{
Console.WriteLine("Fruit Name: {0}, Thread Id= {1}", fruit, Thread.CurrentThread.ManagedThreadId);
});
但这两个代码示例的问题是循环没有按顺序执行。如何使它们按顺序执行?我从别人那里听说,你必须锁定一个物体,然后这是可能的。我试过搜索,试过很多代码示例,但没有用
此外,我想知道按顺序执行的并行循环的性能是否会更低?如果没有,为什么没有?因为锁定,在我看来会导致延迟
至于我对并行编程的理解,调度器在运行时进行调度。有人能告诉我们.NETIDE使用什么算法/策略来调度多个核心上的代码吗?它的好处是由内而外的并行编程。让线程同时并行和顺序运行对您来说真的没有意义 如果
线程3
在线程1
之前完成,会发生什么情况?如果要阻止线程3
并使其等待线程1
完成,那么使用线程有什么意义
但是,如果您希望按顺序完成批处理,这是可能的,但仍然不理想
我的意思是,如果您有一个运行两个线程的列表[1,2,3,4,5,6,7,8,9,10]
,您可以确保1
和2
都在任何其他项之前处理,依此类推。为此,您可以使用以下方法:
void Main()
{
var items = Enumerable.Range(1, 100);
const int numThreads = 4;
foreach(var batch in items.Batch(numThreads))
{
var threads = batch.Select(item => {
return new Thread(() => Console.WriteLine(item));
}).ToList();
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());
}
}
public static class Ext
{
public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(
this IEnumerable<TSource> source, int size)
{
TSource[] bucket = null;
var count = 0;
foreach (var item in source)
{
if (bucket == null)
bucket = new TSource[size];
bucket[count++] = item;
if (count != size)
continue;
yield return bucket;
bucket = null;
count = 0;
}
if (bucket != null && count > 0)
yield return bucket.Take(count);
}
}
void Main()
{
var项目=可枚举范围(1100);
const int numThreads=4;
foreach(items.batch中的var批处理(numThreads))
{
变量线程=批处理。选择(项=>{
返回新线程(()=>Console.WriteLine(item));
}).ToList();
threads.ForEach(t=>t.Start());
threads.ForEach(t=>t.Join());
}
}
公共静态类Ext
{
公共静态IEnumerable批(
此IEnumerable源(整数大小)
{
TSource[]bucket=null;
var计数=0;
foreach(源中的var项)
{
if(bucket==null)
bucket=新的TSource[size];
桶[count++]=物料;
如果(计数!=大小)
继续;
回程铲斗;
bucket=null;
计数=0;
}
if(bucket!=null&&count>0)
产量返回桶。取(计数);
}
}
批处理扩展方法取自让线程并行和顺序运行对您来说并没有什么意义 如果
线程3
在线程1
之前完成,会发生什么情况?如果要阻止线程3
并使其等待线程1
完成,那么使用线程有什么意义
但是,如果您希望按顺序完成批处理,这是可能的,但仍然不理想
我的意思是,如果您有一个运行两个线程的列表[1,2,3,4,5,6,7,8,9,10]
,您可以确保1
和2
都在任何其他项之前处理,依此类推。为此,您可以使用以下方法:
void Main()
{
var items = Enumerable.Range(1, 100);
const int numThreads = 4;
foreach(var batch in items.Batch(numThreads))
{
var threads = batch.Select(item => {
return new Thread(() => Console.WriteLine(item));
}).ToList();
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());
}
}
public static class Ext
{
public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(
this IEnumerable<TSource> source, int size)
{
TSource[] bucket = null;
var count = 0;
foreach (var item in source)
{
if (bucket == null)
bucket = new TSource[size];
bucket[count++] = item;
if (count != size)
continue;
yield return bucket;
bucket = null;
count = 0;
}
if (bucket != null && count > 0)
yield return bucket.Take(count);
}
}
void Main()
{
var项目=可枚举范围(1100);
const int numThreads=4;
foreach(items.batch中的var批处理(numThreads))
{
变量线程=批处理。选择(项=>{
返回新线程(()=>Console.WriteLine(item));
}).ToList();
threads.ForEach(t=>t.Start());
threads.ForEach(t=>t.Join());
}
}
公共静态类Ext
{
公共静态IEnumerable批(
此IEnumerable源(整数大小)
{
TSource[]bucket=null;
var计数=0;
foreach(源中的var项)
{
if(bucket==null)
bucket=新的TSource[size];
桶[count++]=物料;
如果(计数!=大小)
继续;
回程铲斗;
bucket=null;
计数=0;
}
if(bucket!=null&&count>0)
产量返回桶。取(计数);
}
}
批处理扩展方法取自,它们将按顺序执行,首先是For,然后是ForEach。但它们在各自范围内的结果不能保证是按顺序执行的。如果要按顺序执行,请使用
for
和foreach
,对集合进行排序的任何先决条件都会降低它在以并行运行时的性能,甚至可能比按顺序执行的顺序循环更慢,先为后为。但是,它们在各自范围内的结果不能保证是按顺序执行的。如果希望按顺序执行,请使用for
和foreach
,对集合排序的任何先决条件都会降低它在并行运行时的性能,甚至可能比顺序循环慢