Как немедленно остановить запущенный DbContext.SaveChanges () - PullRequest
2 голосов
/ 28 мая 2019

Я сейчас занимаюсь разработкой сервиса.Службы имеют ограниченное время для выключения (4 с).

У меня есть процедура выключения, и это также передает некоторые второстепенные данные через EF6 в базу данных sql.

...

shutdown!

Step1 (останавливает нормальную работу)

step2 передает некоторые данные выключения в db

step3Окончательное завершение работы, удаление всех данных и т. Д.

Приложение имеет более одного контекста и одну стратегию выполнения, настроенную таким образом, что оно повторяется примерно в течение минуты.Я бы хотел оставить это так.

Теперь может случиться так, что база данных не работает - и, таким образом, этот вызов базы данных занимает много времени, максимум 1 минуту, из-за политики выполнения.

Это намного больше, чем 4и поэтому я хотел бы иметь возможность немедленно остановить действие.Я не могу просить больше времени.

Пока я пробовал SaveChangesAsync (cancellationToken);но это все еще продолжается выполнение в течение минуты, отмена токена ничего не делает.Затем я попытался использовать вторую задачу, чтобы вызвать dispose для контекста, закрыть соединение и т. Д. Это иногда казалось работающим, но в других случаях это все еще ждет минуту, прежде чем выдать исключение.

var timeoutTask = Task.Run(() =>
            {
                while (true)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        context.Database.Connection.Close();
                        Debug.WriteLine($"{DateTime.Now:G} {nameof(cancellationToken)} token is canceled!");
                        using(context) { }
                        return;
                    }

                    Task.Delay(10, timeoutTaskTokenSource.Token).Wait(timeoutTaskTokenSource.Token);

                    timeoutTaskTokenSource.Token.ThrowIfCancellationRequested();
                }
            }, cancellationToken);

Rightсейчас я думаю о создании потока и его прерывании, однако надеюсь, что смогу найти более разумное решение.

РЕДАКТИРОВАТЬ:

В строке подключения установлено время ожидания соединения:

Источник данных = localhost; Исходный каталог = MyDb; Интегрированная безопасность = Ложь; ID пользователя = someuser; Пароль = somepassword; MultipleActiveResultSets = True; Время ожидания подключения = 1; Имя приложения = somename; ConnectRetryCount = 0; ConnectRetryInterval = 1

Время ожидания команды равно 1.

1 Ответ

0 голосов
/ 28 мая 2019

Если база данных недоступна, вы можете использовать свойство Connection Timeout вашей строки подключения. Это прервет попытку подключения после задержки.

Если вы хотите прервать команду, вы можете использовать свойство CommandTimeout .

context.Database.CommandTimeout = 5;
...