Вызов хранимой процедуры из другого потока, не работающего на c#, EntityFramework

#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 — вы можете просто вернуть его и позволить вызывающему абоненту беспокоиться об этом