2010-04-21 16 views
7

Ich muss einen Round-Robin-Algorithmus schreiben, um Last auf n Endpunkte zu planen?Load mit einem Round-Robin-Algorithmus einplanen?

Wenn ich also Server A, B und C

wollte ich sicher für jede Anforderung durch sie zu Round-Robin machen ich. Wie mache ich das in C#?

+1

Ist es eine konstante Last oder möchten Sie eine gleichmäßige Lastverteilung? – Avitus

+0

Ich denke, Round Robin zeigt an, dass es keinen Versuch gibt, die Last gleichmäßig zu verteilen. –

Antwort

18

Gerade für die Aufzeichnung, die Definition des round robin:

http://en.wikipedia.org/wiki/Round-robin_scheduling

einfach eine Warteschlange verwenden. Nimm einen von der Spitze, benutze ihn und lege ihn zurück. Dies stellt sicher, dass der zuletzt verwendete immer der letzte sein wird, der abgeholt wird.

Queue<Server> q = new Queue<Server>(); 

//get the next one up 
Server s = q.DeQueue(); 


//Use s; 


//put s back for later use. 
q.Enqueue(s); 

Link zu der Warteschlange Klasse:

http://msdn.microsoft.com/en-us/library/7977ey2c.aspx

+0

Ich würde eine Person herausfordern, die sagte, er wolle Round Robin implementieren, um herauszufinden, ob sie wirklich Round Robin meinen. – Tim

+2

Es wird ständig in der Serverlastverteilung verwendet. – kemiller2002

+1

Wenn Sie dieses Muster verwenden, kann es sich lohnen, den Server sofort in die Warteschlange zu stellen, bevor Sie ihn verwenden (oder die Enqueue in einen finally-Block stellen). Auf diese Weise führen alle Ausnahmen, die beim "Verwenden" des Servers ausgelöst werden, möglicherweise nicht dazu, dass der Server vollständig aus der Rotation entfernt wird. – bvoyelr

1

Wenn Ihre Endpunkte über eine Liste oder Array zugegriffen werden, müssen Sie nur einen Index in einer kreisförmigen Art und Weise erhöhen:

public class RoundRobinIndex 
{ 
    volatile int index = 0; 
    int count; 

    public int Next 
    { 
     get 
     { 
      if (index == count) 
      { 
       index = 0; 
      } 
      return index++; 
     } 
    } 

    public RoundRobinIndex(int countArg) 
    { 
     count = countArg; 
    } 
} 
+0

Die Verwendung wird eine IndexOutOfRangeException verursachen – IBootstrap

+0

@IBootstrap - Es verursacht keine IndexOutOfRangeException. Hast du es tatsächlich getestet? –

+0

Die nächste kann auch erreicht werden mit: (index + 1)% count; – Aerokneeus

6

Die gleiche Idee wie Ebpower, aber konzentrieren sich auf was ist der nächste Artikel und nicht, was ist der Index des nächsten Artikels.

public class RoundRobinList<T> 
{ 
    private readonly IList<T> _list; 
    private readonly int _size; 
    private int _position; 

    public RoundRobinList(IList<T> list) 
    { 
     if (!list.Any()) 
      throw new NullReferenceException("list"); 

     _list = new List<T>(list); 
     _size = _list.Count;    
    } 

    public T Next() 
    { 
     if (_size == 1) 
      return _list[0]; 

     Interlocked.Increment(ref _position); 
     var mod = _position % _size; 
     return _list[mod]; 
    } 
} 
+0

übergeben IEnumerable zu Konstruktor und Rekord mod vor Inkrementieren _position, und das ist Geld. – JJS