7

Initial Situation

I'm developing a .NET Framework 4.0, C#, Winform Application. The Application will list (and test) WebServiceOperations in a GridView (with currently 60 DataRows => WebServiceOperations).

Objective

I have to test/call all of this operations with one click on a button. Every operation creates a new instance of a class. Within this class, i call the WebServiceOperation async and wait for the result. The result is then beeing validated. The whole code works smooth using delegates and events.

Now it comes to the challenge/question: When clicking on that button, i use a for loop (int i = 0; i < gridViewWsOperations.RowCount; i++) => with other words, currently i'm firing 60 operations at them 'same time' => the Server gets overloaded processing 60 requests at the same time and i get timeouts. So i need to somehow throttle the number of concurrend requests to let's say 10 at the same time. Consider, the for loop (where i have to enqueue the requests) isn't in the same thread as the method (process_result event) where i dequeue the requests. I tried it using ConcurrentQueue since this type of collection seems to be thread-safe.

Links

ConcurrentQueue at MSDN

a sample code would really help!

--- this is my solution/sample code ---

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Threading;

namespace ConcurrentQueueSample
{
    class Program
    {
        static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(3);

        static void Main(string[] args)
        {
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timer.Interval = 1234;
            timer.Enabled = true;
            timer.Start();

            for (int i = 0; i < 10; i++) new Thread(go).Start(i);
        }

        static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            semaphoreSlim.Release();
        }

        static void go(object i)
        {
            Console.WriteLine("id: {0}", i);
            semaphoreSlim.Wait();
            Console.WriteLine("id: {0} is in", i);
            Thread.Sleep(1250);
            Console.WriteLine("id: {0} left!", i);
        }
    }
}
Christian Casutt
  • 2,334
  • 4
  • 29
  • 38
  • 3
    Try using a semaphore http://msdn.microsoft.com/en-us/library/system.threading.semaphore.aspx – cadrell0 Jan 23 '13 at 16:26
  • 1
    The `semaphoreSlim.Release()` should not be in a timer, it should be the last thing called in `go`. Also you may want to use a [ThreadPool](http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx) thread instead of a full Thread. – Scott Chamberlain Jan 23 '13 at 17:20
  • You can use a Semaphore within the class calling the web service to limit the number of concurrent requests. – Hylaean Jan 23 '13 at 16:26

1 Answers1

7

You may want to take a look at using the SemaphoreSlim class to throttle the threads that have access to your queue.

Kwal
  • 1,531
  • 7
  • 11