2009-08-02 81 views
5

来自MSDN示例4的示例"Threading Tutorial"
以下代码错误在该行注释“--- errors are here ---”。
有什么不对?为什么来自线程教程的MSDN示例崩溃?

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

对于非通灵,如何发布错误消息....? – 2009-08-02 03:22:58

+0

这里是在System.Threading.WaitHandle.WaitOne(Int64超时,布尔exitContext)\ r \ n在MutexSample.t2Start()在C:\\ Users \中的错误{“等待由于被放弃的互斥体完成。 \ billnewhp \\ AppData \\ Local \\ Temporary Projects \\ ConsoleApplication1 \\ Program.cs:第74行\ r \ n在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)\ r \ n at System.Threading.ThreadHelper.ThreadStart()“ – user149169 2009-08-02 03:33:12

回答

6

等待一个互斥锁后,必须释放它,使用

Mutex.ReleaseMutex() 
线程退出前

固定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(); 
}