2013-01-23 25 views
6

Situazione inizialeC# strozzamento ciclo For

sto sviluppando un .NET Framework 4.0, C#, Winform applicazione. L'applicazione elencherà (e testerà) WebServiceOperations in un GridView (con attualmente 60 DataRows => WebServiceOperations).

Obiettivo

devo testare/chiamare tutto questo le operazioni con un solo clic su un pulsante. Ogni operazione crea una nuova istanza di una classe. All'interno di questa classe, chiamo WebServiceOperation async e attendo il risultato. Il risultato sarà quindi convalidato. L'intero codice funziona senza problemi con i delegati e gli eventi.

Ora si tratta della sfida/domanda: Quando si fa clic su tale pulsante, io uso un ciclo for (int i = 0; i < gridViewWsOperations.RowCount; i ++) => con altre parole, attualmente io sono attivando 60 operazioni "nello stesso momento" => il server viene sovraccaricato elaborando 60 richieste allo stesso tempo e ricevo i timeout. Quindi ho bisogno di in qualche modo limitare il numero di richieste simultanee per dire 10 allo stesso tempo. Si consideri che il ciclo for (dove devo accodare le richieste) non si trova nello stesso thread del metodo (evento process_result) dove rimuovo le richieste. L'ho provato usando ConcurrentQueue poiché questo tipo di raccolta sembra essere thread-safe.

Link

ConcurrentQueue at MSDN

un codice di esempio sarebbe di grande aiuto!

--- questo è il mio codice di soluzione/campione ---

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); 
     } 
    } 
} 
+3

Provare a utilizzare un semaforo http://msdn.microsoft.com/en-us/library/system.threading.semaphore.aspx – cadrell0

+1

Il 'semaphoreSlim.Release()' non deve essere in un timer, dovrebbe essere il l'ultima cosa chiamata in 'go'. Potresti anche voler utilizzare un thread [ThreadPool] (http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx) anziché un thread completo. –

+0

È possibile utilizzare un semaforo all'interno della classe che chiama il servizio Web per limitare il numero di richieste simultanee. – Hylaean

risposta

5

Si consiglia di dare un'occhiata al utilizzando la classe SemaphoreSlim di strozzare i fili che hanno accesso alla coda.