开发者

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:

  • ID : 6 --> A
  • ID : 13 --> A
  • ID : 6 --> 2A
  • ID : 12 --> A
  • ID : 13 --> 2A
  • ID : 15 --> A
  • ID : 6 --> 3A
  • ID : 12 --> 2A
  • ID : 14 --> A
  • ID : 13 --> 3A

(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?

  • ID : 6 --> A
  • ID : 13 --> 2A
  • ID : 6 --> 3A
  • ID : 12 --> 4A
  • ID : 13 --> 5A
  • ID : 15 --> 6A
  • ID : 6 --> 7A
  • ID : 12 --> 8A
  • ID : 14 --> 9A
  • ID : 13 --> 10A

Appreciate any开发者_JAVA百科 help. Thanks alot.


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜