GetAwaiter не работает, чтобы дождаться завершения метода Clear библиотеки Quartz - есть ли ошибка в Quartz или пробел в моем понимании? - PullRequest
0 голосов
/ 24 января 2020

В последней версии библиотеки 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...

Большое спасибо за вашу помощь !!

1 Ответ

0 голосов
/ 27 января 2020

.GetAwaiter() возвращает только TaskAwaiter, вам нужно запросить результат у ожидающего, даже если это просто Задача без типа результата (void). Чтобы дождаться завершения задания, просто позвоните: myScheduler.Clear().GetAwaiter().GetResult();

...