Yagiz Ozturk
Yagiz Ozturk

Reputation: 5428

ThreadPool Asynchronised Threads in Same Method

I have a question regarding ThreadPool usage at a point. After I run simple below code. I get the result:

(this goes on...) Here is my code :

static void Main(string[] args)
{
    Program p = new Program();
    p.Start();
    Console.ReadLine();
}

private void Start()
{
    System.Timers.Timer senderTimer;
    senderTimer = new System.Timers.Timer();
    senderTimer.Elapsed += new System.Timers.ElapsedEventHandler(SenderTimer);
    senderTimer.Interval = 500;
    senderTimer.Enabled = true;
}

private void SenderTimer(object Source, ElapsedEventArgs e)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(Foo));
}

private void Foo(object state)
{
    string[] array = new string[] { "A", "2A", "3A", "4A", "5A", "6A", "7A", "8A", "9A", "10A" };

    for (int i = 0; i < array.Length; i++)
    {
        Trace.WriteLine("ID : " + Thread.CurrentThread.GetHashCode() + " --> " + array[i]);
        Thread.Sleep(1000); // Here I have a DB Operation, so i make it sleep
    }
}

What I need to get as a result is that multiple threads doing the same thing synorinized. Here is the output I must get: Hope I explained clearly. Is there a way to do that?

Appreciate any help. Thanks alot.

Upvotes: 0

Views: 208

Answers (2)

Muhammad Hasan Khan
Muhammad Hasan Khan

Reputation: 35126

If you want to force the order of processing then there is no point in making it multithreaded since every thread anyway will wait for the previous one.

If you want to do the processing in parallel but then put the results in the same order they were received then you can use

        string[] array = new string[] { "A", "2A", "3A", "4A", "5A", "6A", "7A", "8A", "9A", "10A" };
        var results = array.AsParallel().Select((item, i) =>
        new
        {
            Index = i,
            Result = ProcessItem(item)
        })
        .OrderBy(x => x.Index)
        .Select(i=>i.Result)
        .ToList();

Upvotes: 1

skaz
skaz

Reputation: 22580

You should have the array of numbers to print outside of your Foo function. If it is inside, every thread will try to process the full list, but that isn't what you want (as far as I can tell).

You want to make a new function, say GetNextItemToProcess that will return the next item in the array that has not yet been processed. Then, in your Foo function, call something like

lock(this)
{
   string nextItem = GetNextItemToProcess();
   Trace.WriteLine("ID : " + Thread.CurrentThread.GetHashCode() + " --> " + nextItem );
}

Since each thread needs to ensure it grabs the next item correctly, you need to lock. IMPORTANT NOTE: locking the whole function, while ensuring what you want, isn't good for multithreading. With this method it might as well have been serial. Threading will really give you the benefit if each item of work can be executed in an arbitrary order, which isn't the case here. If you really need the output to come "A, 2A, 3A" you are better off doing it serially. If it can come "2A, A, 3A" or a random order where each item is expected to show up exactly once, threading is what you want.

Upvotes: 0

Related Questions