How to add to the list when using multithreading?

I'm a little new to Multi-Threading and have just played with it in the past. But I am curious if it is possible to have a list of byte arrays in the main stream and can still be added to this list when creating a new byte array in a separate stream. In addition, I will use a for-each loop that will go through a list of forms that will be used for analysis in an array of bytes. So basically pseudo-code will be like this ...

reports = new List();

foreach (form in forms)  
{  
    newReport = new Thread(ParseForm(form));  
    reports.Add(newReport);  

}  

void ParseForm(form)  
{  
    newArray = new byte[];  
    newArray = Convert.ToBytes(form);  
    return newArray;  
}

Hope the pseudo code above makes sense. If anyone could tell me if this is possible and point me towards a good example, I’m sure I can figure out the actual code.

+5
source share
4 answers

, , SynchronizedCollection, .NET 3,0 .

:

SynchronizedCollection reports = new SynchronizedCollection();

foreach (form in forms) {  
    var reportThread = new Thread(() => ParseForm(form, reports));
    reportThread.Start();
}

void ParseForm(Form form, SynchronizedCollection reports) {  
    newArray = new byte[];  
    newArray = Convert.ToBytes(form);  
    reports.Add(newArray);
}

.NET 4 , ​​ System.Threading.Tasks namespace. , .

+3

, , .Net 3.5, .Net 4

- , "" ConcurrentBag <T> . , ConcurrentQueue <T> .

- , , BlockingCollection <T> . .

Parallel.Foreach, :

private void ParseForms()
{
    var reports = new ConcurrentBag<byte[]>();
    Parallel.ForEach(forms, (form) =>
                                {
                                    reports.Add(ParseForm(form));
                                });

}

private byte[] ParseForm(form)  
{  
    newArray = new byte[];  
    newArray = Convert.ToBytes(form);  
    return newArray;  
}
+2

, ?

. , , .

.

using System.Threading.Tasks

-

Files.Clear(); //List<string> 

Task.Factory.StartNew( () =>
{
      this.BeginInvoke( new Action(() =>
         {
            Files.Add("Hi");
         }));
 });
0

Below is a simple assembly of locks (only in the queue), which I just whipped, since you do not have access to C # 4.0. It is most likely less efficient than 4.0 concurrent collections, but it should work quite well. I didn’t reimplement all Queue methods, just in line, crossed out and looked. If you need others and cannot understand how they will be implemented, just mention this in the comments.

Once you have a working blocking collection, you can simply add to it from producer flows and delete it using consumer flows.

public class MyBlockingQueue<T>
{
    private Queue<T> queue = new Queue<T>();
    private AutoResetEvent signal = new AutoResetEvent(false);
    private object padLock = new object();

    public void Enqueue(T item)
    {
        lock (padLock)
        {
            queue.Enqueue(item);
            signal.Set();
        }
    }

    public T Peek()
    {
        lock (padLock)
        {
            while (queue.Count < 1)
            {
                signal.WaitOne();
            }

            return queue.Peek();
        }
    }

    public T Dequeue()
    {
        lock (padLock)
        {
            while (queue.Count < 1)
            {
                signal.WaitOne();
            }

            return queue.Dequeue();
        }
    }
}
0
source

All Articles