LoggerBase クラスがあります。次のようになります。
public class BatchLoggerBase : IDisposable
{
protected string LogFilePath { private get; set; }
protected object _synRoot;
BatchLoggerBase(string logFilePath)
{
LogFilePath = logFilePath;
}
protected virtual void WriteToLog(string message)
{
Task.Factory.StartNew(() =>
{
lock (_synRoot)
{
System.IO.File.AppendAllText(LogFilePath, message);
}
});
}
//Other code...
}
次のように、この基本クラスから継承する別のクラスがあります。
public sealed class TransactionBatchLogger : BatchLoggerBase
{
public TransactionBatchLogger()
{
_synRoot = new object();
string directory = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["Batch.TransactionLog.Path"];
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
LogFilePath = string.Format("{0}{1}_{2}.txt", directory, "TransactionLog", DateTime.Now.ToString("yyyy-MM-dd"));
}
public void LogLoyaltyPointProcess(IEnumerable<CustomerTierOverrideItem> listOfCustomerTierItem)
{
Task.Factory.StartNew(() =>
{
//Construct message...
WriteToLog(message);
});
}
}
public sealed class LoyaltyPointBatchLogger : BatchLoggerBase
{
public LoyaltyPointBatchLogger()
{
_synRoot = new object();
string directory = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["Batch.LoyaltyPointLog.Path"];
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
LogFilePath = string.Format("{0}{1}_{2}.txt", directory, "LoyaltyPointLog", DateTime.Now.ToString("yyyy-MM-dd"));
}
public void LogLoyaltyPointProcess(IEnumerable<CustomerTierOverrideItem> listOfCustomerTierItem)
{
Task.Factory.StartNew(() =>
{
//Construct message...
WriteToLog(message);
});
}
}
LoyaltyPointBatchLogger と TransactionBatchLogger はログ コンテンツを異なるログ ファイル (1 つは transactionLog 用、もう 1 つは LoayltyPointLog 用) に書き込みますが、それらはすべて基本クラスから同じ仮想メソッドを呼び出します。
バッチ プログラムはバッチごとにデータ バッチを処理します (合計 45000 データと各バッチ 10000 のように) これら 2 つのロガーは異なるバッチによって連続して呼び出される可能性があるため、ログ ファイルが異なるバッチ ロガー スレッドによってアクセスされることは望ましくありません。
問題は、_synRoot を派生クラス LoyaltyPointBatchLogger と TransactionBatchLogger、または基本クラスでインスタンス化する必要があるかどうかです。
LoyaltyPointBatchLogger と TransactionBatchLogger でインスタンス化された _synRoot は異なる参照であるため、LoyaltyPointBatchLogger と TransactionBatchLogger は、lock ステートメントに入ったときに互いに待機しませんよね?