Я заметил странную проблему с Nlog при записи журналов в базу данных через несколько потоков.
Проблема в том, что журнал для одной базы данных иногда добавляется в другую базу данных, т. Е. Иногда смешивается. Является ли метод обновления DbTarget из Nlog не безопасным для потоков или я что-то здесь не так делаю?
Пожалуйста, поделитесь своими идеями / опытом, чтобы справиться с этим.
Я использую одно и то же приложение для трех разных клиентов, у каждого из которых три разные базы данных на одном сервере. У меня есть приложение C # Windows, где есть 3 потока, которые созданы для 3 разных баз данных. Каждый поток имеет дело со своей собственной базой данных так, как показано здесь:
public void StartService()
{
string conn1 = connectionstring for database1;
string conn2 = connectionstring for database2;
Thread ThreadDB1 = new Thread(new ThreadStart(() => Process(conn1)));
Thread ThreadDB2 = new Thread(new ThreadStart(() => Process(conn2)));
ThreadDB1.Start();
ThreadDB2.Start();
}
public void Process(string domainCon)
{
this.isActive = true;
while (this.isActive)
{
try
{
StartOperation(domainCon);
}
catch (Exception ex)
{
//since the Nlog has not been initialised for an individual threads that switch per database,
//If any error occurs here, log that in event log instead
EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error);
}
}
}
public static void StartOperation(string domainCon)
{
NLogLoggerService loggerService;
NLogLogger Logger;
/* Set the "NEW" instance of logger here so that each instance
* will be per thread (i.e per database) */
Logger = new NLogLogger("MyAppName_Processor");
loggerService = new NLogLoggerService(Logger);
//create the DbTarget that is passed by current thread
Logger.UpdateNLogDatabase(domainCon);
// the process to select the records from Db happens here
ProcessDbRecords(domainCon);
}
ProcessDbRecords(domainCon)
{
//Records are selected, analyzed processed and saved again in database for each thread
//the following log is written in database but log of one database is written in another database sometimes
loggerService.LoggerInfo("The Database has been called for connString: " + domainCon);
}
//in LogService class, i have a method that updates the database target with connectionstring provided in runtime:
public static void UpdateNLogDatabase(string connString)
{
var config = LogManager.Configuration;
var dbTarget = (Targets.DatabaseTarget)config.FindTargetByName("Database");
dbTarget.ConnectionString = connString;
LogManager.ReconfigExistingLoggers();
}