我有一个 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 将日志内容写入不同的日志文件(一个用于 transactionLog,另一个用于 LoayltyPointLog),但它们都从基类调用相同的虚拟方法。
批处理程序逐批处理数据(例如,总数据45000个,每批10000个)这两个记录器可能会被不同的批次连续调用,所以我不希望日志文件被不同的批次记录器线程访问。
问题是:我应该在派生类 LoyaltyPointBatchLogger 和 TransactionBatchLogger 中还是在基类中实例化 _synRoot?
LoyaltyPointBatchLogger 和 TransactionBatchLogger 中实例化的 _synRoot 是不同的引用,所以 LoyaltyPointBatchLogger 和 TransactionBatchLogger 在进入 lock 语句时不会互相等待,对吧?