2009-08-02 8 views
5

À partir de l'exemple de l'exemple 4 de MSDN "Threading Tutorial"
Les erreurs de code suivantes sur la ligne ont commenté avec "--- errors is here ---".
Qu'est-ce qui ne va pas?Pourquoi l'exemple MSDN du didacticiel Threading se bloque-t-il?

using System; 
using System.Threading; 

public class MutexSample 
{ 
    static Mutex gM1; 
    static Mutex gM2; 
    const int ITERS = 100; 
    static AutoResetEvent Event1 = new AutoResetEvent(false); 
    static AutoResetEvent Event2 = new AutoResetEvent(false); 
    static AutoResetEvent Event3 = new AutoResetEvent(false); 
    static AutoResetEvent Event4 = new AutoResetEvent(false); 

    public static void Main(String[] args) 
    { 
     Console.WriteLine("Mutex Sample ..."); 
     // Create Mutex initialOwned, with name of "MyMutex". 
     gM1 = new Mutex(true, "MyMutex"); 
     // Create Mutex initialOwned, with no name. 
     gM2 = new Mutex(true); 
     Console.WriteLine(" - Main Owns gM1 and gM2"); 

     AutoResetEvent[] evs = new AutoResetEvent[4]; 
     evs[0] = Event1; // Event for t1 
     evs[1] = Event2; // Event for t2 
     evs[2] = Event3; // Event for t3 
     evs[3] = Event4; // Event for t4 

     MutexSample tm = new MutexSample(); 
     Thread thread1 = new Thread(new ThreadStart(tm.t1Start)); 
     Thread thread2 = new Thread(new ThreadStart(tm.t2Start)); 
     Thread thread3 = new Thread(new ThreadStart(tm.t3Start)); 
     Thread thread4 = new Thread(new ThreadStart(tm.t4Start)); 
     thread1.Start(); // Does Mutex.WaitAll(Mutex[] of gM1 and gM2) 
     thread2.Start(); // Does Mutex.WaitOne(Mutex gM1) 
     thread3.Start(); // Does Mutex.WaitAny(Mutex[] of gM1 and gM2) 
     thread4.Start(); // Does Mutex.WaitOne(Mutex gM2) 

     Thread.Sleep(2000); 
     Console.WriteLine(" - Main releases gM1"); 
     gM1.ReleaseMutex(); // t2 and t3 will end and signal 

     Thread.Sleep(1000); 
     Console.WriteLine(" - Main releases gM2"); 
     gM2.ReleaseMutex(); // t1 and t4 will end and signal 

     // Waiting until all four threads signal that they are done. 
     WaitHandle.WaitAll(evs); 
     Console.WriteLine("... Mutex Sample"); 
    } 

    public void t1Start() 
    { 
     Console.WriteLine("t1Start started, Mutex.WaitAll(Mutex[])"); 
     Mutex[] gMs = new Mutex[2]; 
     gMs[0] = gM1; // Create and load an array of Mutex for WaitAll call 
     gMs[1] = gM2; 
     Mutex.WaitAll(gMs); // Waits until both gM1 and gM2 are released 
     Thread.Sleep(2000); 
     Console.WriteLine("t1Start finished, Mutex.WaitAll(Mutex[]) satisfied"); 
     Event1.Set();  // AutoResetEvent.Set() flagging method is done 
    } 

    public void t2Start() 
    { 
     Console.WriteLine("t2Start started, gM1.WaitOne()"); 
     gM1.WaitOne(); // Waits until Mutex gM1 is released ---errors is here--- 
     Console.WriteLine("t2Start finished, gM1.WaitOne() satisfied"); 
     Event2.Set();  // AutoResetEvent.Set() flagging method is done 
    } 

    public void t3Start() 
    { 
     Console.WriteLine("t3Start started, Mutex.WaitAny(Mutex[])"); 
     Mutex[] gMs = new Mutex[2]; 
     gMs[0] = gM1; // Create and load an array of Mutex for WaitAny call 
     gMs[1] = gM2; 
     Mutex.WaitAny(gMs); // Waits until either Mutex is released 
     Console.WriteLine("t3Start finished, Mutex.WaitAny(Mutex[])"); 
     Event3.Set();  // AutoResetEvent.Set() flagging method is done 
    } 

    public void t4Start() 
    { 
     Console.WriteLine("t4Start started, gM2.WaitOne()"); 
     gM2.WaitOne(); // Waits until Mutex gM2 is released 
     Console.WriteLine("t4Start finished, gM2.WaitOne()"); 
     Event4.Set(); // AutoResetEvent.Set() flagging method is done 
    } 
} 
+1

pour la non-psychique, que diriez-vous afficher le message d'erreur ....? –

+0

Voici l'erreur {"L'attente est terminée en raison d'un mutex abandonné."} À System.Threading.WaitHandle.WaitOne (Int64 timeout, Boolean exitContext) \ r \ n à MutexSample.t2Start() dans C: \\ Users \ \ billnewhp \\ AppData \\ Local \\ Projets temporaires \\ ConsoleApplication1 \\ Program.cs: ligne 74 \ r \ n System.Threading.ExecutionContext.Run (ExecutionContext executionContext, rappel ContextCallback, état de l'objet) \ r \ n at System.Threading.ThreadHelper.ThreadStart() " – user149169

+0

Il s'agit de cet exemple MSDN, qui semble brisé http://msdn.microsoft.com/en-us/library/aa645740(VS.71).aspx#vcwlkthreadingtutorialexample4mutex –

Répondre

6

Après avoir attendu sur un Mutex vous devez libérer, en utilisant

Mutex.ReleaseMutex() 

avant que les sorties de fils.

fixe t1start - t4start

public void t1Start() 
{ 
    Console.WriteLine("t1Start started, Mutex.WaitAll(Mutex[])"); 
    Mutex[] gMs = new Mutex[2]; 
    gMs[0] = gM1; // Create and load an array of Mutex for WaitAll call 
    gMs[1] = gM2; 
    Mutex.WaitAll(gMs); // Waits until both gM1 and gM2 are released 
    Thread.Sleep(2000); 
    Console.WriteLine("t1Start finished, Mutex.WaitAll(Mutex[]) satisfied"); 
    Event1.Set();  // AutoResetEvent.Set() flagging method is done 
    gM1.ReleaseMutex(); 
    gM2.ReleaseMutex(); 
} 
public void t2Start() 
{ 
    Console.WriteLine("t2Start started, gM1.WaitOne()"); 
    gM1.WaitOne(); // Waits until Mutex gM1 is released ---errors is here---  
    Console.WriteLine("t2Start finished, gM1.WaitOne() satisfied"); 

    gM1.ReleaseMutex(); 
    Event2.Set();  // AutoResetEvent.Set() flagging method is done 

} 
public void t3Start() 
{ 
    Console.WriteLine("t3Start started, Mutex.WaitAny(Mutex[])"); 
    Mutex[] gMs = new Mutex[2]; 
    gMs[0] = gM1; // Create and load an array of Mutex for WaitAny call 
    gMs[1] = gM2; 

    int result = Mutex.WaitAny(gMs); // Waits until either Mutex is released 
    gMs[result].ReleaseMutex(); 
    Console.WriteLine("t3Start finished, Mutex.WaitAny(Mutex[])"); Event3.Set();  // AutoResetEvent.Set() flagging method is done 
} 
public void t4Start() 
{ 
    Console.WriteLine("t4Start started, gM2.WaitOne()"); 
    gM2.WaitOne(); // Waits until Mutex gM2 is released 
    Console.WriteLine("t4Start finished, gM2.WaitOne()"); 
    Event4.Set(); // AutoResetEvent.Set() flagging method is done 
    gM2.ReleaseMutex(); 
} 
+0

Merci, releaseMutex() résoudre le problème – user149169

+0

+1 Vous auriez gagné [5+ times upvotes] (http://stackoverflow.com/questions/6464219/why-does-this-sample -code-de-Microsoft-crash/6464324 # 6464324) ainsi que empêché plus tard dupes avez-vous édité les balises et le titre de la question –

+0

Dommage, qu'un tutoriel MSDN doit être corrigé ici sur SO. – VSZM