使用ThreadPool.QueueUserWorkItem对线程进行排序 [英] Ordering of thread using ThreadPool.QueueUserWorkItem

查看:207
本文介绍了使用ThreadPool.QueueUserWorkItem对线程进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是线程基础的新手。

我有一个操作队列要对XML文件(节点添加,节点删除等)执行

I have a queue of operations to be performed on a XML files(node add,node delete etc)

1]有'n'个xml文件,每个文件使用
ThreadPool.QueueUserWorkItem来分配线程池中的线程。

1]There are 'n' xml files and for each file a thread from thread pool is allocated using ThreadPool.QueueUserWorkItem to do those file operations.

我想使用线程实现并发和操作顺序(重要)。

例如:假设操作[a1,a2,a3,a4,a5]要对文件B.xml...执行文件A.xml

和操作[b1,b2,b3,b4,b5,b6,b7] 。

我要分配线程,以便我可以在

相同的顺序中并且同时(因为文件不同)执行这些操作。

I want to achieve both concurrency and ordering of operation(important) using threads.
eg: Suppose if operations [a1,a2,a3,a4,a5] are to be performed on file "A.xml"
and operations [b1,b2,b3,b4,b5,b6,b7] are to be performed on file "B.xml" .....
I want to allocated threads such that i can perform these operations in the
same order and also concurrently(since files are different).

2]也可以为每个操作分配一个线程并实现concurency和保持顺序。

2]Also is it possible to assign each operation a thread and achieve concurency and preserve order.

在STA模型中, / p>

In STA model i did something similar..

while(queue.count>0){
  File f = queue.Dequeue(); //get File from queue       
  OperationList oprlst = getOperationsForFile(f); 
// will get list-> [a1,a2,a3,a4,a5]   
  for each Operation oprn in oprlst 
  {
    performOperation(f,oprn)
    //in MTA i want to wait till operation "a1" completes and then operation "a2" will
   //start.making threads wait till file is in use or operation a(i) is in use.
  }    
}

我想同时操作操作顺序保存。
线程可以等待一个文件...但
不同的操作需要不同的执行时间。

i want to do this concurrently with operation order preservation. Threads(of operation) can wait on one file...but Different operations take different execution times.

我试过AutoResetEvent和WaitHandle。 WaitAll(..),但它使while循环
停止,直到所有'a(i)'操作完成。我想同时执行a(i)和b(j)。
(但是在(i)和b(j)中排序)

i tried AutoResetEvent and WaitHandle.WaitAll(..) but it made the while loop stop untill all 'a(i)' operations finish..i want both a(i) and b(j) perform concurrently. (but ordering in a(i) and b(j))

目前使用.net 2.0。

Currently using .net 2.0 .

这很相似,并且是此问题的一部分问题< a>

This is quite similar and is part of this question asked Question

推荐答案

你应该避免使用 Monitor 以及 ThreadPool 线程中的 WaitHandle 结构,因为这些线程被其他进程使用。你需要你的线程基于个别文件。如果单个文件不需要那么长的时间来处理(并且没有太多的文件),那么 ThreadPool 将工作。

You should avoid using thread blocking techniques like Monitor locks and WaitHandle structures in ThreadPool threads, since those threads are used by other processes. You need to have your threading be based around individual files. If an individual file doesn't take that long to process (and you don't have too many files), then the ThreadPool will work.

您可以在以文件为中心的方法上使用 EnqueueUserWorkItem 。 ..something like this:

You could just use EnqueueUserWorkItem on a file-centric method...something like this:

private void ProcessFile(Object data)
{ 
    File f = (File)data;

    foreach(Operation oprn in getOperationsForFile(f))
    {
        performOperation(f, oprn);
    }
}

然后在处理文件的代码中:

Then in your code that processes the files, do this:

while(queue.Count > 0)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessFile), queue.Dequeue());
}

如果你需要你的调用线程阻塞,直到他们都完成, WaitHandle 是确定(因为您封锁了自己的主题, ThreadPool )。然而,你必须创建一个小的有效载荷类来传递给线程:

If you need your calling thread to block until they are all complete, then a WaitHandle is OK (since you're blocking your own thread, not the ThreadPool thread). You will, however, have to create a small payload class to pass it to the thread:

private class Payload
{
    public File File;
    public AutoResetEvent Handle;
}

private void ProcessFile(Object data)
{ 
    Payload p = (Payload)data;

    foreach(Operation oprn in getOperationsForFile(p.File))
    {
        performOperation(f, oprn);
    }

    p.Handle.Set();
}

...

WaitHandle[] handles = new WaitHandle[queue.Count];
int index = 0;

while(queue.Count > 0)
{        
    handles[index] = new AutoResetEvent();

    Payload p = new Payload();

    p.File = queue.Dequeue();
    p.Handle = handles[index];

    ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessFile), p);

    index++;
}

WaitHandle.WaitAll(handles);



线程实现



你有大量的文件(或可能需要大量的时间为您的文件处理),然后创建自己的线程是一个更好的主意。这也允许你省略 WaitHandle s。

private void ProcessFile(File f)
{     
    foreach(Operation oprn in getOperationsForFile(f))
    {
        performOperation(f, oprn);
    }

    p.Handle.Set();
}

private object queueLock = new object();

private void ThreadProc()
{
    bool okToContinue = true;

    while(okToContinue)
    {
        File f = null;

        lock(queueLock)
        {
            if(queue.Count > 0) 
            {
                f = queue.Dequeue();
            }
            else
            {
                f = null;
            }
        }

        if(f != null)
        {
            ProcessFile(f);
        }
        else
        {
            okToContinue = false;
        }
    }
}

...

Thread[] threads = new Thread[20]; // arbitrary number, choose the size that works

for(int i = 0; i < threads.Length; i++)
{
    threads[i] = new Thread(new ThreadStart(ThreadProc));

    thread[i].Start();
}

//if you need to wait for them to complete, then use the following loop:
for(int i = 0; i < threads.Length; i++)
{
    threads[i].Join();
}

上述示例是一个非常 ,但它应该说明需要做什么。

The preceding example is a very rudimentary thread pool, but it should illustrate what needs to be done.

这篇关于使用ThreadPool.QueueUserWorkItem对线程进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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