对于循环的Parallel.For优先集 [英] set priority for Parallel.For loop

查看:351
本文介绍了对于循环的Parallel.For优先集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,这里的情况:我的主/ UI线程(称之为线程1)用于从phsycial文档扫描仪获取一批图像。当一批已经被收购,一个独立的后台线程(称之为线程2)启动以处理来自该批次保存图像。



线程2(背景线程)是使用的Parallel.For 循环从而降低了图像处理/ 70%,比正常的节省了时间循环。然而,这似乎也即将用尽我所有的处理器,使线程1无法启动收购任何更多的图像,直到的Parallel.For 循环完成。



有没有一种方法来限制一的Parallel.For 循环,使其不最大程度的发挥我的处理器?或以设置的处理优先级?我尝试设置 Thread2.Priority = ThreadPriority.Lowest ,但这似乎并没有影响到循环。还是我误解如何的Parallel.For 循环的作品?难道阻塞线程1不知何故?



下面是我如何调用线程2在线程1的方法。

 公共无效SaveWithSettings(布尔保存)//方法线程1 
{
....
导线THR =新主题(ThreadWork); //创建新的线程(线程2)
thr.Priority = ThreadPriority.Lowest; // 什么也没做?
thr.Start(新SaveContainer(SC)); //传递一个副本paramater

//其它的东西,使扫描可能再次
numBgw ++;
twain.RemoveAllImages(); //清晰的图像
imagelist.Clear(); //清晰的图像列表图像
.... //等等这一切看起来工艺精细,而线程2处理
}

下面是我的 ThreadWork 方法:

 私人无效ThreadWork(对象数据)//在线程2 
{
SaveContainer SC =数据SaveContainer执行; //保存图像

布尔[] = blankIndex新布尔[sc.imagelist.Count] //中的Parallel.For循环
用的for(int i = 0; I< sc.imagelist.Count;我++)
blankIndex [I] = FALSE; //设置默认值设置为false(不为空)

的Parallel.For(0,sc.imagelist.Count,我= GT; //循环标记空白影像
{
布尔X = FALSE; //本地变量使循环更加高效
X = sc.IsBlankImage((短)我); //检查是否索引i图像是空白
blankIndex [I] = X; //设置,如果图像是空白
}
.... //其他图像处理步骤
}


解决方案

OK,我想它了!我只张贴这万一有人无意中过这已经发生在自己身上......



原来,在的Parallel.For 线程不会阻塞线程1(是的,你都是对的)。但是,一个对象在线程1试图抓住一个新的线程池而循环在啃了,因此延迟出现。我使用的是第三方的SDK,让我与TWAIN接口进行交互,并有一个选项 ScanInNewThread = TRUE 这是试图抓住每一个新的线程一次用户开始新的扫描(这是同时循环在啃走存在的)。我能够改变这个使一个单一的(但仍分开)的线程在整个应用程序会话中使用抢夺一个新的线程为每个扫描批次,而是和砰的一声,没有更多明显的延迟。



SO - 这个故事的寓意是:



现有线程应该仍然起作用正常(与线程调用<$ C $异常C>的Parallel.For 循环),只要他们不试图从线程池而循环会抢占更多的线程。


Ok, here's the situation: My main/UI thread (call it Thread1) is used for acquiring a batch of images from a phsycial document scanner. When a batch has been acquired, a separate "background" thread (call it Thread2) starts up to process and save the images from that batch.

Thread2 (the "background" thread) is using a Parallel.For loop which reduces the image processing/saving time by 70% over a normal For loop. However, it also appears to be maxing out all of my processors so that Thread1 can not start acquiring any more images until the Parallel.For loop completes.

Is there a way to "limit" a Parallel.For loop so that it does not max out my processors? Or to set the processing priority? I tried setting Thread2.Priority = ThreadPriority.Lowest, but this does not appear to affect the loop. Or am I misunderstanding how a Parallel.For loop works? Is it blocking Thread1 somehow?

Here is how I call the Thread2 from a method in Thread1.

public void SaveWithSettings(bool save) // method in Thread1
{
    ....
    Thread thr = new Thread(ThreadWork); // creating new thread (Thread 2)
    thr.Priority = ThreadPriority.Lowest; // does nothing?
    thr.Start(new SaveContainer(sc)); // pass a copy as paramater

    // misc stuff to make scanning possible again
    numBgw++;
    twain.RemoveAllImages(); // clear images
    imagelist.Clear(); // clear imagelist images
    .... // etc. this all appears to process fine while Thread2 is processing
}

Here is my ThreadWork method:

private void ThreadWork(object data) // executing in Thread2
{
    SaveContainer sc = data as SaveContainer; // holds images

    bool[] blankIndex = new bool[sc.imagelist.Count]; // to use in Parallel.For loop
    for (int i = 0; i < sc.imagelist.Count; i++)
        blankIndex[i] = false; // set default value to false (not blank)

    Parallel.For(0, sc.imagelist.Count, i => // loop to mark blank images
    {
        bool x = false; // local vars make loop more efficient
        x = sc.IsBlankImage((short)i); // check if image at index i is blank
        blankIndex[i] = x; // set if image is blank
    }
    .... // other image processing steps
}

解决方案

OK, I figured it out! I'm only posting this in case someone ever inadvertantly has this happen to them...

It turns out that the Parallel.For thread was NOT blocking Thread1 (yes, you were all right). HOWEVER, an object in Thread1 was trying to grab a new Thread from the ThreadPool while the loop was crunching away, and thus the "delay" occured. I'm using a 3rd party SDK that allows me to interact with the TWAIN interface and there was an option ScanInNewThread = true that was attempting to grab a new thread each time the user started a new scan (which was occuring while the loop was crunching away). I was able to change this so that a single (but still separate) thread is used throughout an application session instead of grabbing a new thread for each scan batch, and BANG, no more noticeable delay.

SO - the moral of the story:

Existing threads should still function "normally" (with the exception of the thread calling the Parallel.For loop) as long as they are not trying to grab more threads from the ThreadPool while the loop is going.

这篇关于对于循环的Parallel.For优先集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆