2017-04-26 25 views
0

私はMutexを使って、同じファイルに別のプロセス/アプリケーションを書き込もうとしています。named Mutexの使い方

これはFileLogはILogTestの実装である私のコード

ILogTest logTest = new LogTest(new FileLog()); 
logTest.PerformanceTest(); 


    public class ILogTest 
    { 
      public void PerformanceTest() 
      { 
       for (int i = 0; i < this.numberOfIterations; i++) 
       { 
        try 
        { 
         Thread threadC = Thread.CurrentThread; 
         threadC = new Thread(ThreadProc); 
         threadC.Name = i.ToString(); 
         threadC.Start(); 
         threadC.Suspend(); 
         threadC.IsBackground = true; 
        } 
        catch (Exception) 
        { 
         throw new Exception("errore"); 
        } 
       } 
      } 

      private void ThreadProc() 
      { 
       try 
       { 
        log.Write("Thread : " + Thread.CurrentThread.Name.ToString()); 
        this.log.Write("Thread : " + Thread.CurrentThread.Name.ToString()); 
        this.log.Write("Thread : " + Thread.CurrentThread.Name.ToString()); 
        this.log.Write("Thread : " + Thread.CurrentThread.Name.ToString()); 
       } 
       catch (Exception) 
       { 
        throw new Exception("errore"); 
       } 
      } 
    } 

です。

Writeメソッド:メイン

public void Write(string message) 
    { 
     try 
     { 
      rwl.WaitOne(); 
      try 
      { 
       string tID = Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.CurrentCulture); 

       sw.WriteLine(sev.ToString() + "\t" + DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss", CultureInfo.CurrentCulture) + "\t\t" + System.Reflection.Assembly.GetCallingAssembly().GetName().Name + "\t" + Process.GetCurrentProcess().Id.ToString(CultureInfo.CurrentCulture) + "\t" + tID + " \t " + message); 


       sw.WriteLine("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"); 
      } 
      catch (Exception ex) 
      { 
       throw new ArgumentException("Cannot write to file " + ex.Message); 
      } 
      finally 
      { 
       rwl.ReleaseMutex(); 
      } 
     } 
     catch (ApplicationException) 
     { 
     } 
    } 

FileLog:

public FileLog() 
    { 
     try 
     { 
      rwl.WaitOne(); 
      string filePath = Path.GetTempPath() + "Test.txt"; 
      if (!File.Exists(filePath)) 
      { 
       swa = new FileStream(filePath, FileMode.Append, FileAccess.Write); 
       sw = new StreamWriter(swa); 
      } 
     } 
     catch (Exception ex) 
     { 
      throw new ArgumentException("Cannot open or create file " + ex.Message); 
     } 

     try 
     { 
      if (sw == null) 
      { 
       swa = new FileStream(filePath, FileMode.Append, FileAccess.Write); 
       sw = new StreamWriter(swa); 
      } 

      sw.AutoFlush = true; 
     } 
     catch (Exception ex) 
     { 
      throw new ArgumentException("Cannot write to file " + ex.Message); 
     } 
    } 

がそれをシミュレートしようと、それだけで、それを作成し、ファイルに何も書き込みません。.. 私は理由を知りません。 誰か助けてくれますか?おかげ

+0

ファイルのロックが良好ではないでしょうか? https://msdn.microsoft.com/en-us/library/system.io.filestream.lock(v=vs.110).aspx –

+0

@AdamBensonこれは、他のすべてのスレッド/プロセスが同時に書き込みを試みる必要があるファイルが現在ロックされているときに生成される 'IOException'を処理します。実際には理想的ではないかもしれない競合に応じて。 –

+0

[InterProcessLock](https://logging.apache.org/log4net/release/sdk/html/T_log4net_Appender_FileAppender_InterProcessLock.htm)ロックモデルを使用して、log4netのFileAppenderの使用を検討してください。あなたがする必要がなければ車輪を再発明しないでください。 (どのようにして行うことができるかは、少なくとも[その実装](https://github.com/apache/log4net/blob/fa13c71e628fd0a59880ecb50e79dc0d5724fa39/src/Appender/FileAppender.cs#L723)を使用してください) –

答えて

1

FileLogコンストラクタは(私はrwlMutexオブジェクトであると仮定しています)ミューテックスを取得しますが、rwl.ReleaseMutex()を呼び出すことはありませんrwl.WaitOne()を呼び出します。

したがって、Write()を呼び出すすべてのスレッドは、mutexが別のスレッドによって引き続き所有されているため、rwl.WaitOne()を呼び出してブロックされます。

FileLogコンストラクタでMutexを解放し、他のスレッドが取得できるようにする必要があります。

また、threadC.Suspend();PerformanceTestに電話しています。スレッドを再開するコードがない限り、スレッドは実行を終了しません。

関連する問題