2016-03-27 4 views
0

So habe ich eine grundlegende Lösung für das Problem des Dining Tutor unter:C# - Looping wird nicht aufhören (jede Iteration startet neue Aufgabe)

using System; 
using System.Threading.Tasks; 

namespace Conductor 
{ 
    class Program 
    { 
     private static object _locker = new object(); 

     static void Main(string[] args) 
     { 
      object[] sticks = {new object(), 
           new object(), 
           new object(), 
           new object(), 
           new object()}; 

      for (int i = 0; i<5; i++) 
      { 
       int next = (i + 1) % 5; 
       Task.Factory.StartNew(() => Eat(sticks[i], sticks[next], i)); 
      } 
     } 

     static void Eat(object _leftChopstick, object _rightChopstick, int i) 
     { 
      lock (_locker) 
      { 
       lock (_leftChopstick) 
       { 
        lock (_rightChopstick) 
        { 
         Console.WriteLine("Eating" + i); 
        } 
       } 
      } 
     } 
    } 
} 

Zwar ist es nicht die effizienteste Lösung sein kann, wirft es eine Ausnahme von IndexOutOfRange beim Aufruf von "StartNew", wenn i auf 5 gesetzt ist. Ich kann nicht herausfinden, wie meine Task Factory die For-Loop-Bedingung irgendwie ignoriert hat.

Wenn ich diesen Code ausführen, es ist in Ordnung:

using System; 
using System.Threading.Tasks; 

namespace Conductor 
{ 
    class Program 
    { 
     private static object _locker = new object(); 

     static void Main(string[] args) 
     { 
      object[] sticks = { new object(), 
           new object(), 
           new object(), 
           new object(), 
           new object()}; 

      int i = 0; 
      Task.Factory.StartNew(() => Eat(sticks[i], sticks[i + 1], i)); 
      Task.Factory.StartNew(() => Eat(sticks[i+1], sticks[i + 2], i + 1)); 
      Task.Factory.StartNew(() => Eat(sticks[i+2], sticks[i + 3], i + 2)); 
      Task.Factory.StartNew(() => Eat(sticks[i+3], sticks[i + 4], i + 3)); 
      Task.Factory.StartNew(() => Eat(sticks[i + 4], sticks[0], i + 4)); 
      Console.ReadLine(); 
     } 

     static void Eat(object _leftChopstick, object _rightChopstick, int i) 
     { 
      lock (_locker) 
      { 
       lock (_leftChopstick) 
       { 
        lock (_rightChopstick) 
        { 
         Console.WriteLine("Eating" + i); 
        } 
       } 
      } 
     } 
    } 
} 

Auch, wenn ich durch die Schleife debuggen, erhalte ich die gleiche Ausnahme.

Jede Hilfe mit diesem würde sehr geschätzt werden. Tut mir leid, wenn es zu einfach ist oder wenn ich einen Fehler in meinem Code habe, den ich verpasst habe. Vielen Dank.

+1

den Debugger verwenden und Schritt durch den Code .. nicht nur 'CODE UND GO' Code schreiben bedeutet, und starten Sie die Anwendung erwarten' Zero' Fehler zu haben .. – MethodMan

+0

Yep habe ich das auch. Ich habe meine Antwort bearbeitet, um das zu sagen. Prost sowieso. –

Antwort

0
for (int i = 0; i < 5; i++) 
      { 
       int j = i; 
       int next = (i + 1) % 5; 
       Task.Factory.StartNew(() => Eat(sticks[j], sticks[next], j)); 
      } 
+0

Das Problem war in der Bereich Änderung der Verweis auf "i", wenn Task.Factory beteiligt war. Indem Sie eine lokale Variable zuweisen, die nur von einem einzelnen Zielprozess konsumiert wird, vermeiden Sie das Risiko, dass die höhere Bereichsvariable durch externe Faktoren modifiziert wird. – Jace

Verwandte Themen