2016-09-28 16 views
0

スレッドhereに関してこの記事を読んでいました。 セクションの下では、以下のコードがミューテックスにありました。ブロックを使用しているミューテックスの動作が異なります

class OneAtATimePlease 
{ 
    static void Main() 
    { 
    // Naming a Mutex makes it available computer-wide. Use a name that's 
    // unique to your company and application (e.g., include your URL). 

    using (var mutex = new Mutex (false, "oreilly.com OneAtATimeDemo")) 
    { 
     // Wait a few seconds if contended, in case another instance 
     // of the program is still in the process of shutting down. 

     if (!mutex.WaitOne (TimeSpan.FromSeconds (3), false)) 
     { 
     Console.WriteLine ("Another app instance is running. Bye!"); 
     return; 
     } 
     RunProgram(); 
    } 
    } 

    static void RunProgram() 
    { 
    Console.WriteLine ("Running. Press Enter to exit"); 
    Console.ReadLine(); 
    } 
} 

しかし、私はこれを実行すると、期待どおりのコードは「さようなら。別のアプリケーションインスタンスが実行されている!」私はexeファイル(上記の生成されたexeファイル)を実行する場合は二回、それはを印刷する必要があり、動作していません。しかし、そのブロックには向かない。

しかし、私が使用ブロックを削除すると、コードは正しく動作します。

私を助けてください。私はスレッドの概念に新しいです。

UPDATE誤解を招くため

申し訳ありません。私は実際にその記事に正確に書かれたようにはしませんでした。

私のコードそのまま、

internal class Program 
{ 
    /// <summary> 
    /// Entry point 
    /// </summary> 
    /// <param name="args">The arguments.</param> 
    internal static void Main(string[] args) 
    { 
     //Misc.RunAssemblies(); 

     var threadingDemo = new ThreadingDemo(); 
     threadingDemo.MutexDemo(); 

     Console.ReadLine(); 
    } 
} 

namespace LearnNet.Console 
{ 
    using System.Threading; 

    public class ThreadingDemo 
    { 
     public void MutexDemo() 
     { 
      using (var mutex = new Mutex(false, "Global\\oreilly.com OneAtATimeDemo")) 
      { 
       // Wait a few seconds if contended, in case another instance 
       // of the program is still in the process of shutting down. 
       if (!mutex.WaitOne(0, false)) 
       { 
        System.Console.WriteLine("Another app instance is running. Bye!"); 
        return; 
       } 

       RunProgram(); 
      } 
     } 

     static void RunProgram() 
     { 
      System.Console.WriteLine("Running. Press Enter to exit"); 
     } 
    } 
} 

これは私が上記で説明し、問題を再現します。私は使用してブロックを削除する場合、それは正しく動作します。

+0

最初のコードは正常に動作しており、2番目のインスタンスを実行すると "Bye"と表示されます。 – Evk

+0

こんにちは、お返事ありがとうございます。私は問題がある。私はポストを更新します。 – shanmugharaj

+0

@Evk更新された質問を確認してください。これは問題を再現します。 – shanmugharaj

答えて

1

mutexの仕組みを理解する必要があります。 WaitOneを取得し、ReleaseMutexまたはそれを処分するとがリリースされます。ブロックを使用し終わると(制御フローがそれを離れるとき)、mutexはDisposedになります(そのため、最初にブロックが使用される理由です)。更新されたコードでは、mutexが取得され、RunProgramステートメントの後にすぐに解放され、後続のインスタンスも取得して即座に解放します。

ブロックを使用していないときは、Disposeのミューテックスがないので、ミューテックスを解放しないでください。 Console.ReadLineステートメントを実行すると、プロセスはまだmutexを保持します。あなたのプロセスが終了したら、mutexはまだリリースされていますが、それはあまり良い方法ではありません。

あなたが掲示した最初のコード(更新前)の理由は - Console.ReadLine()ステートメントはブロックを使用しているので、このステートメントプロセスの制御フローブロックはまだミューテックスを保持しています。

+0

Ohh私の悪い。今私はそれが分かりました。実際に私はクラスに論理を分けたコードでConsole.ReadLineを見逃してしまったのを見ていませんでした。とてもばか。あなたの時間を無駄にして申し訳ありません。ありがとう! – shanmugharaj

関連する問題