2010-03-31 3 views
12

Abbiamo una situazione in cui vogliamo limitare il numero di richieste paralell che la nostra applicazione può apportare al suo server applicazioni. Abbiamo potenzialmente più di 100 thread in background in esecuzione che vorranno a un certo punto effettuare una chiamata al server delle applicazioni ma vogliono solo 5 thread per poter chiamare SendMessage() (o qualunque sia il metodo) in qualsiasi momento. Qual è il modo migliore per raggiungere questo obiettivo?Limitare il numero di thread che eseguono un metodo in una sola volta

Ho considerato l'utilizzo di una sorta di oggetto gatekeeper che blocca i thread che arrivano nel metodo finché il numero di thread in esecuzione non è sceso sotto la soglia. Questa sarebbe una soluzione ragionevole o sto trascurando il fatto che questo potrebbe essere sporco/pericoloso?

Stiamo sviluppando in C# .NET 3.5.

Grazie,

Steve

risposta

1

La classe Semaphore è stata progettata esattamente per questo scenario.

10

Volete un semaforo ... System.Threading.Semaphore

public static class MyClass 
{ 
    private static Semaphore sem = new Semaphore(5, 5); 

    public static void SendMessage() 
    { 
     sem.WaitOne(); 

     try 
     { 
     } 
     finally 
     { 
      sem.Release(1); 
     } 
    } 
} 

In alternativa, se si desidera solo un singolo thread per essere in grado di chiamare un metodo in un dato momento, .NET espone anche un concetto equivalente con l'attributo di Java sincronizzato:

[System.Runtime.CompilerServices.MethodImpl(MethodImpl.Synchronized)] 
+1

probabilmente si desidera rilasciare il semaforo anche se un'eccezione * non viene * generata. Inseriscilo nel blocco finally –

+0

oops, il mio male, grazie – LorenVS

+3

L'attributo di sincronizzazione a livello di metodo non è valido. Si blocca su "questo" per esempio i membri e ancor peggio, il tipo per i membri statici. Non dovrebbe mai essere usato. – Josh

1

design pattern approccio: - Usa sequenza comando con cinque fili Executor e avvolgere le vostre richieste nelle classi Command.