#c# #multithreading #entity-framework
Вопрос:
У меня есть хранимая процедура для очистки некоторых данных.
Когда я вызываю из Program.cs, например, следующее, это не работает
static void Main(string[] args)
{
LogCleaner logCleaner = new LogCleaner(appConfiguration);
Task.Run(() => logCleaner.Start());
}
ОчиСтитель журналов.Запустите функцию следующим образом
try
{
using(UnitOfWork unitOfWork = new UnitOfWork(this.appConfiguration.DefaultConnectionString))
{
var result = unitOfWork.E3DLogs.CleanUpLogs(this.appConfiguration.CleanUpDayCount);
logger.Info("Clean up stored procedure executed, Result: " result.ToString());
}
}
catch (Exception e)
{
logger.Error("Error while cleaning the log messages. Error Message: " e.Message);
}
Модульная работа.электронные журналы.Очистите журналы следующим образом
public int CleanUpLogs(int dayCount)
{
return _E3DDbcontext.CleanUpLogs(dayCount);
}
_e3ddbконтекст.CleanUpLogs работают следующим образом
public virtual int CleanUpLogs(Nullable<int> dayCount)
{
var dayCountParameter = dayCount.HasValue ?
new ObjectParameter("dayCount", dayCount) :
new ObjectParameter("dayCount", typeof(int));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("CleanUpLogs", dayCountParameter);
}
Когда я вызываю из Program.cs, например, после его работы
static void Main(string[] args)
{
LogCleaner logCleaner = new LogCleaner(appConfiguration);
logCleaner.Start();
}
Комментарии:
1. Вы никогда не ждете задачу, созданную в task.run(). Может ли быть так, что программа завершает работу быстрее, чем может выполнить задача?
2. Пожалуйста, определите «это не работает» — что на самом деле происходит
Ответ №1:
Процесс (exe) завершается, когда завершается последний не фоновый поток, что для простых приложений означает: когда Main
завершается. Пул потоков, в котором службы Task.Run
используют фоновые потоки, поэтому они не учитываются с точки зрения срока службы приложения.
Запуск кода напрямую предотвращает это. В качестве альтернативы вы могли бы сделать (если это уместно):
static Task Main(string[] args)
{
LogCleaner logCleaner = new LogCleaner(appConfiguration);
var logCleaner = Task.Run(() => logCleaner.Start());
// presumably some other code to run here, because if there wasn't:
// you'd just run logCleaner.Start() directly
return logCleaner; // include the log-cleaner in the application lifetime
}
Комментарии:
1. Не было бы больше смысла делать
await logCleaner;
и делатьMain
асинхронно2. @Charlieface если бы у вас были другие асинхронные задачи
Main
, то это имело бы смысл; в противном случае в этом нет необходимостиawait
— вы можете просто вернуть его и позволить вызывающему абоненту беспокоиться об этом