Order thread using ThreadPool.QueueUserWorkItem

I am new to the basics of threads.

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

1] There are "n" xml files, and for each file, a thread is allocated from the thread pool using ThreadPool.QueueUserWorkItem to perform these file operations.

I want to achieve both concurrency and ordering operations (important) using threads.
  for example: suppose that operations [a1, a2, a3, a4, a5] should be performed in the file “A.xml”
  and operations [b1, b2, b3, b4, b5, b6, b7] should be performed in the file “B. xml ".....
I want to allocate threads so that I can perform these operations in the same order as well as at the same time (since the files are different).

2] You can also assign a stream to each operation and achieve consistency and maintain order.

In the 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 while maintaining the order of operations. Themes (operations) can wait on one file ... but Different operations take different execution times.

I tried AutoResetEvent and WaitHandle.WaitAll (..), but did a while loop until all the "a (i)" operations finished. I want both (i) and b (j) to be executed simultaneously. (but ordering in (i) and b (j))

Currently using .net 2.0.

This is very similar and is part of this question asked by Question

+3
source share
3 answers

, Monitor WaitHandle ThreadPool, . , . ( ), ThreadPool .

ThreadPool

EnqueueUserWorkItem ... - :

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

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

, , :

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

, , , WaitHandle ( , ThreadPool). , :

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.

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();
}

- , , .

+2

, ThreadPool.QueueUserWorkItem - , , , . parallelism , .

+5

, , , . , ().

0

Source: https://habr.com/ru/post/1724505/


All Articles