Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在维护顺序的同时对循环执行多线程_C#_Multithreading_Parallel Processing - Fatal编程技术网

C# 在维护顺序的同时对循环执行多线程

C# 在维护顺序的同时对循环执行多线程,c#,multithreading,parallel-processing,C#,Multithreading,Parallel Processing,我开始为我正在运行的CPU密集型批处理进程处理多线程。本质上,我试图将多个单页TIFF压缩成单个PDF文档。这在foreach循环或标准迭代中可以很好地工作,但对于几个100页的文档来说可能非常慢。我根据我发现的一些使用多线程的示例尝试了以下内容,它有显著的性能改进,但是它删除了页面顺序,而不是1,2,3,4。线程首先完成的是1,3,4,2,6,5 我的问题是,在维护页面顺序的同时,我将如何利用这种技术,如果可以,它是否会抵消多线程的性能优势?先谢谢你 PdfDocument doc = new

我开始为我正在运行的CPU密集型批处理进程处理多线程。本质上,我试图将多个单页TIFF压缩成单个PDF文档。这在foreach循环或标准迭代中可以很好地工作,但对于几个100页的文档来说可能非常慢。我根据我发现的一些使用多线程的示例尝试了以下内容,它有显著的性能改进,但是它删除了页面顺序,而不是1,2,3,4。线程首先完成的是1,3,4,2,6,5

我的问题是,在维护页面顺序的同时,我将如何利用这种技术,如果可以,它是否会抵消多线程的性能优势?先谢谢你

PdfDocument doc = new PdfDocument();
string mail = textBox1.Text;
string[] split = mail.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);

int counter = split.Count();

// Source must be array or IList.
var source = Enumerable.Range(0, 100000).ToArray();
// Partition the entire source array.
var rangePartitioner = Partitioner.Create(0, counter);
double[] results = new double[counter];
// Loop over the partitions in parallel.
Parallel.ForEach(rangePartitioner, (range, loopState) =>
{
    // Loop over each range element without a delegate invocation.
    for (int i = range.Item1; i < range.Item2; i++)
    {
        f_prime = split[i].Replace(" " , "");
        PdfPage page = doc.AddPage();
        XGraphics gfx = XGraphics.FromPdfPage(page);
        XImage image = XImage.FromFile(f_prime);
        double x = 0;
        gfx.DrawImage(image, x, 0);

    }
});
PdfDocument doc=新的PdfDocument();
字符串mail=textBox1.Text;
string[]split=mail.split(新字符串[]{Environment.NewLine},StringSplitOptions.None);
int counter=split.Count();
//源必须是数组或IList。
var source=Enumerable.Range(0,100000).ToArray();
//对整个源阵列进行分区。
var rangePartitioner=Partitioner.Create(0,计数器);
double[]结果=新的double[计数器];
//并行地在分区上循环。
Parallel.ForEach(rangePartitioner,(range,loopState)=>
{
//在没有委托调用的情况下在每个范围元素上循环。
对于(int i=range.Item1;i
我将使用Parallel.ForEach的重载返回元素索引:

 Parallel.ForEach(rangePartitioner, (range, loopState, elementIndex) =>
然后在循环中,您可以用工作结果填充一个数组,并在结果全部完成后按顺序遍历这些结果。

使用.AsParallel().AsOrdered(),如本文档所述:

我想它会像这样:

rangePartitioner.AsParallel().AsOrdered().ForAll(
    range => 
    {
        // Loop over each range element without a delegate invocation.
        ...
    });

我不确定其他解决方案是否会完全按照他想要的方式工作。原因是
PdfPage page=doc.AddPage()同时创建并添加一个新页面,因此它将始终处于无序状态,因为通过
doc

如果
AddPage
是一个快速操作,则可以一次创建所有100页,而无需任何处理。然后返回并将Tiff图像呈现到页面中

PdfDocument doc = new PdfDocument();
string mail = textBox1.Text;
string[] split = mail.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);

int counter = split.Count();

// Source must be array or IList.
var source = Enumerable.Range(0, 100000).ToArray();
// Partition the entire source array.
var rangePartitioner = Partitioner.Create(0, counter);

double[] results = new double[counter];

PdfPage[] pages = new PdfPage[counter];
for (int i = 0; i < counter; ++i) 
{
    pages[i] = doc.AddPage();
}

// Loop over the partitions in parallel.
Parallel.ForEach(rangePartitioner, (range, loopState) =>
{
    // Loop over each range element without a delegate invocation.
    for (int i = range.Item1; i < range.Item2; i++)
    {
        f_prime = split[i].Replace(" " , "");
        PdfPage page = pages[i];
        XGraphics gfx = XGraphics.FromPdfPage(page);
        XImage image = XImage.FromFile(f_prime);
        double x = 0;
        gfx.DrawImage(image, x, 0);
    }
});
PdfDocument doc=新的PdfDocument();
字符串mail=textBox1.Text;
string[]split=mail.split(新字符串[]{Environment.NewLine},StringSplitOptions.None);
int counter=split.Count();
//源必须是数组或IList。
var source=Enumerable.Range(0,100000).ToArray();
//对整个源阵列进行分区。
var rangePartitioner=Partitioner.Create(0,计数器);
double[]结果=新的double[计数器];
PdfPage[]页=新PdfPage[计数器];
对于(int i=0;i<计数器;++i)
{
pages[i]=doc.AddPage();
}
//并行地在分区上循环。
Parallel.ForEach(rangePartitioner,(range,loopState)=>
{
//在没有委托调用的情况下在每个范围元素上循环。
对于(int i=range.Item1;i
编辑

我认为有一个更优雅的解决方案,但在不了解PdfPage属性的情况下,我以前不想提供它。如果你能分辨出一个PfdPage属于哪一页,你可以把事情变得非常简单,比如:

PdfDocument doc = new PdfDocument();
string mail = textBox1.Text;
string[] split = mail.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);

int counter = split.Count();

// Source must be array or IList.
var source = Enumerable.Range(0, 100000).ToArray();
// Partition the entire source array.
var rangePartitioner = Partitioner.Create(0, counter);

double[] results = new double[counter];

// Loop over the partitions in parallel.
Parallel.ForEach(rangePartitioner, (range, loopState) =>
{
    // Loop over each range element without a delegate invocation.
    for (int i = range.Item1; i < range.Item2; i++)
    {
        PdfPage page = doc.AddPage();
        // Only use i as a loop not as the index
        int pageIndex = page.PageIndex; // This is what I don't know
        f_prime = split[pageIndex].Replace(" " , "");
        XGraphics gfx = XGraphics.FromPdfPage(page);
        XImage image = XImage.FromFile(f_prime);
        double x = 0;
        gfx.DrawImage(image, x, 0);
    }
});
PdfDocument doc=新的PdfDocument();
字符串mail=textBox1.Text;
string[]split=mail.split(新字符串[]{Environment.NewLine},StringSplitOptions.None);
int counter=split.Count();
//源必须是数组或IList。
var source=Enumerable.Range(0,100000).ToArray();
//对整个源阵列进行分区。
var rangePartitioner=Partitioner.Create(0,计数器);
double[]结果=新的double[计数器];
//并行地在分区上循环。
Parallel.ForEach(rangePartitioner,(range,loopState)=>
{
//在没有委托调用的情况下在每个范围元素上循环。
对于(int i=range.Item1;i
我认为这需要一个探查器来确定处理过程中的主要问题在哪里发生。使用elementIndex可以处理的唯一内容是XImage image=XImage.FromFile(f_prime);因为其他一切都需要基于给定代码的PdfPage。这很可能就是他需要并行化的全部,但如果不分析它,就不可能说出来。+1:我直到第二次通读才意识到这一点,但你是对的。将doc.AddPage()从循环中拉出是确保页面有序的唯一方法。感谢您的帮助,我还没有尝试过它,但快速看一下,这看起来是一个很好的解决方案。。