2012-01-17 1 views
0

私はテキストファイルとしてログを書き込むプログラムを持っています。スレッドを呼び出してC言語のテキストファイルにログするより良い方法

namespace logging 
{ 
    using System; 
    using System.IO; 
    using System.Reflection; 
    using System.Runtime.InteropServices; 
    using System.Text; 

    public class log 
    { 
     private static string lpath; 

     [DllImport("kernel32")] 
     private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); 
     public static void Info(string user, string info, string txt) 
     { 
      StreamWriter writer; 
      string str = Assembly.GetExecutingAssembly().GetName().CodeBase.ToString(); 

      ..... 

      if (!File.Exists(path)) 
      { 
       writer = new StreamWriter(path, true); 
       writer.WriteLine(str3 + " " + info + " => " + txt); 
       writer.Flush(); 
       writer.Close(); 
      } 
      else 
      { 
       writer = File.AppendText(path); 
       writer.Write(str3 + " " + info + " => " + txt + "\n"); 
       writer.Flush(); 
       writer.Close(); 
      } 
     } 
    } 
} 

次に機能があります。インナー機能(BoardingPass_Print()BaggageTag_Print())の

private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    Thread thread_BP_Print = new Thread(BoardingPass_Print);   
    thread_BP_Print.Start(); 

    // Simultaneously, do something on the main thread. 
    BaggageTag_Print(); 
    bgw.RunWorkerAsync(); 
} 

二つは同一のロギング機能を呼び出します。そのため、私の呼び出し元のスレッド法の

logging.log.Info(username, "Query Trace > ", sql); 

、私はエラーに直面思う:

The process cannot access the file 'C:\Folder\2012-01-17-Name.txt' because it is being used by another process.

は、誰も私にこのようなエラーメッセージが直面することなく、テキストファイルへの糸と、ロギングと対話するためのよりよい解決策を与えてもらえますか?

すべての提案は本当に感謝しています。

答えて

1

スレッドセーフ(lock)を作成する必要があります。現在のコードも例外セーフではありません。 両方の問題を適切なライブラリメソッドを使用して解決できます。

複数のプロセスからのファイルへの安全なアクセスを保証することはできませんが、アプリケーションの1つのインスタンスによって書き込まれている限り、スレッドを同期できます。

private static object locker = new object(); 
public static void Info(string user, string info, string txt) 
{   
    string str = Assembly.GetExecutingAssembly().GetName().CodeBase.ToString(); 
    string str3 = ... 
    lock (locker) 
    { 
     File.AppendAllText(path, str3 + " " + info + " => " + txt + "\n"); 
    } 
} 

AppendAllText静的メソッドである、それは正しく、新規/既存のファイルの問題とリソース管理を処理します。

1

独自のログ機能を記述するのではなく、スレッドセーフであるlog4netを使用できます。

1

クラシックバージョンは次のようになります。

  • は、専用のロガーのスレッドを持って AutoResetEvent
  • で待機している時間のほとんどは、(スレッドセーフ)キュー
  • ロギングがそれに書き込むことによって開始され、持っていますロガースレッドは、ウェイクアップしたファイルにキューを空にし、その後、 が再び
  • 眠る AutoResetEvent
  • をキューと設定

事前に開発されたフレームワークから選択することも、依存関係を避けたい場合は、いくつかの行で独自のロールをとることができます。

1

NLog、log4Net、エンタープライズライブラリなどのように、独自のロギングロジックを使用すると、既に提供されている製品として包括的ではありません。

しかし、そのままにしたい場合は、ログ情報をキュー(MSMQなど)に送信し、別のプロセスでキューをポーリングして情報をテキストファイルに保存することをお勧めします。

1

ロギングフレームワークを使用しない場合は、スレッドセーフであるためには少なくともlockステートメントを使用する必要があります。

静的メソッドの代わりにSingletonを使用して、アプリケーションが終了するまでログファイルを開いたままにすることもできます。

関連する問題