2012-05-01 6 views
1

私はMutexを試していて、次のコードを書いています。なぜApplicationExceptionがスローされるのですか?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 

namespace Mutex_WaitOnewithTimeouts 
{ 
    class Program 
    { 
     private static Mutex mut = new Mutex(); 
     private static int numOfThreads = 5; 
     private static int numOfIterations = 3; 
     private static Random rand = new Random(); 

     static void Main(string[] args) 
     { 
      Thread[] threads = new Thread[5]; 
      for (int num = 0; num < numOfThreads; num++) 
      { 
       threads[num] = new Thread(new ThreadStart(MyThreadProc)); 
       threads[num].Name = String.Format("Thread{0}", num); 
       threads[num].Start(); 
      } 
      Console.Read(); 
     } 

     private static void MyThreadProc() 
     { 
      for (int iteration = 0; iteration < numOfIterations; iteration++) 
      { 
       UseResource(); 
      } 
     } 

     private static void UseResource() 
     { 
      Console.WriteLine("{0} accessing ", Thread.CurrentThread.Name); 
      int time = (int)(rand.NextDouble() * 100); 
      try 
      { 
       if (mut.WaitOne(time)) 
       { 
        Console.WriteLine("Yippie got mutex for {0}", Thread.CurrentThread.Name); 
        Thread.Sleep((int)rand.NextDouble() * 5000); 
       } 
       else 
       { 
        Console.WriteLine("Nopee.... Timeout occured for {0}", Thread.CurrentThread.Name); 
       } 
      } 
      catch (AbandonedMutexException ex) 
      { 
       Console.WriteLine(" Exception is caught"); 
      } 
      finally 
      { 
       Console.WriteLine("Releasing mutex for {0}", Thread.CurrentThread.Name); 
       mut.ReleaseMutex(); 

      } 

     } 
    } 
} 

誰かが私のコードに何か問題がある場合は、私を助けてくださいとも、この例外のトリガーがする時に説明していただけます私は...時々ApplicationExceptionをを取得しています。

コードの非同期ブロックからオブジェクト同期メソッドが呼び出されました。私はmutexをリリースしようとしたときにfinallyブロックでこれを取得しています。

+0

例外からのラインの上のカップルを示し、それはあなたのサンプルコードでのスローされているもののラインを示すために、あなたの投稿を編集してください。 – Gray

+0

'ApplicationException'はあなたがそれから派生した例外を個人的に作成したときにのみ見受けられます。あなたは見ている 'ApplicationException'ですか?あるいは、代わりに 'TargetInvocationException'や' WaitHandleCannotBeOpenedException'のような派生した例外がありますか? – user7116

+0

例外のメッセージは何ですか?内部の例外はありますか?任意の手がかりのスタックトレースを見ましたか? – sellmeadog

答えて

7

WaitOneが失敗した場合でも、ミューテックスを解放しています。 ReleaseMutex呼び出しを、if文の中で移動します。どこにmutexがあるか知っています。ジョンの答え@

+0

ありがとう@John Koerner ..それはうまくいきました...私は疑問に思っていました。私のコードを変更してelse partは – Shrikey

+0

@Shrikeyを実行します。releaseMutex呼び出しをIfステートメントに移動します。あるいは、ロックが取得されたときにtrueに設定されたブール値を設定し、それが真である場合にのみ解放します。 –

+0

それは働いた..ありがとう.. :) – Shrikey

0

は正しいですが、後世のために、私はより良いパターンがifでtrueにブール値を設定し、ブール値があるならば、まだfinallyブロックでreleaseが、今回はそれだけをやるんだと思います本当。問題は、句のいずれかがスローすると、ミューテックスが解放されないことです。私はあなたが書き込みと睡眠よりも多くをif句に追加すると仮定します。

可能であればtry { ... } finallyパターンを使用しますが、waitOne()コールがfalseを返すことから保護するだけです。以下のような何か:

bool release = false; 
try { 
    if (mut.waitOne(time)) { 
     release = true; 
     ... 
    } else { 
     ... 
    } 
} catch (AbandonedMutexException ex) { 
    ... 
} finally { 
    ... 
    if (release) { 
     mut.ReleaseMutex(); 
    } 
} 
+1

いいえ、これは動作しません。ミューテックスは、いつでも1つのスレッドだけがコードの領域にアクセスできるようにする同期メカニズムです。あるスレッドでnullに設定した場合、次のスレッドがそのコードに到達すると、null参照例外がスローされます。 –

+0

ダー、右@ジョン感謝。私はそれが静的であることを忘れていた。私は代わりにブール値を使うように答えました。 – Gray

関連する問題