В последней версии библиотеки Quartz все переключено на использование async / await. Вызывающее приложение имеет синхронные вызовы, которые очень встроены во фреймворк, поэтому я застрял с вызовом .GetAwaiter () (я знаю, что это не идеально. Это консольное приложение, поэтому не должно возникать взаимоблокировок из-за наличия только одного потока пользовательского интерфейса).
Мне нужно очистить базу данных расписания, дождаться завершения команды Очистить и снова заполнить базу данных в определенном сценарии ios. Я вызываю .GetAwaiter () для метода Clear в Quartz, но он не ждет - то есть следующая строка после строки .GetAwaiter запускается ДО всего кода, который должен ожидаться.
Я предполагаю, что с большой работой (и без повышения производительности, так как мне нужно .GetAwaiter () в любом случае), я мог бы реорганизовать, по крайней мере, вызов Clear () и методов для планирования большего количества заданий из того же асинхронного метода и вызовите .GetAwaiter () на более высоком уровне, но я не уверен, что это сработает - если .GetAwaiter () не будет ждать, как должно, "лучше" будет работать? "
Of Конечно, я мог бы написать свои собственные sql вызовы, чтобы очистить базу данных напрямую, что мне, возможно, придется сделать в конце, но мне не имеет смысла делать это, когда у Quartz есть метод Clear в своем планировщике.
Мой вызов метода Clear планировщика Quartz очень прост:
myScheduler.Clear().GetAwaiter();
Я обнаружил, что строка кода AFTER, которая вызывается ДО кода в методе StdAdoDelegate.ClearData в Quartz, и я Я думал, что мой вызов GetAwaiter () предотвратит это. Это ошибка в Quartz, и если да, что не так с кодом библиотеки Quartz? Или что-то не так с тем, как я об этом думаю?
Вот схема кода, вызываемого при вызове метода Clear () Quartz:
StdScheduler:
Task Clear(cancellationToken)
return sched.Clear(cancellationToken);
QuartzScheduler:
async Task Clear(cancellationToken = default)
await resources.JobStore.ClearAllSchedulingData(cancellationToken).ConfigureAwait(false);
JobStoreSupport:
Task ClearAllSchedulingData
return ExecuteInLock(LockTriggerAccess, conn => ClearAllSchedulingData(conn, cancellationToken), cancellationToken);
async Task ExecuteInLock(lockName, txCallback, cancellationToken=default)
await ExecuteInLock<object>(lockName, async conn =>
{
await txCallback(conn).ConfigureAwait(false);
return null;
}, cancellationToken).ConfigureAwait(false);
JobStoreTX (which inherits from JobStoreSupport):
Task<T> ExecuteInLock<T>(lockName, txCallback, cancellationToken)
return ExecuteInNonManagedTXLock(lockName, txCallback, cancellationToken);
JobStoreSupport:
Task<T> ExecuteInNonManagedTXLock(lockName, txCallback, cancellationToken)
T result = await txCallback(conn).ConfigureAwait(false);
(stack trace returns first to ExecuteInLock<T>, then to ExecuteInLock, and then to ClearAllSchedulingData as callback is called)
async Task ClearAllSchedulingData(conn, cancellationToken)
await Delegate.ClearData(conn, cancellationToken).ConfigureAwait(false);
StdAdoDelegate:
async Task ClearData(conn, cancellationToken=default)
DbCommand ps = PrepareCommand(conn, ReplaceTablePrefix(SqlDeleteAllSimpleTriggers));
await ps.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
ps = PrepareCommand(conn, ReplaceTablePrefix(SqlDeleteAllSimpropTriggers));
await ps.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
And more similar calls...
Большое спасибо за вашу помощь !!