Сбой при попытке вызвать асинхронный долго работающий сохраненный Proc из C # - PullRequest
1 голос
/ 04 октября 2019

У меня есть длительная хранимая процедура, spLongRunningProcess, когда я вызываю ее с помощью Async Await, она запускается и выполняется просто отлично, однако мне нужно вызывать ее, не дожидаясь ответа, потому что это очень длительный процесс .. Вот мойКод ниже, я что-то упустил, но не могу это прибить.

public async Task<ResultObject> LongSPCallAsync()
{
    ResultObject ro = new ResultObject();
    try
    {
        using (_context = new DbContext())
        {
            SqlParameter returnVal2 = new SqlParameter("@ReturnVal2", SqlDbType.Int)
            {
                Direction = ParameterDirection.Output
            };

            _context.Database.ExecuteSqlCommandAsync("EXEC @ReturnVal2 = [spLongRunningProcess]", returnVal2).ConfigureAwait(false);  //<-- This NEVER runs unless I await it.? 
            var oooo = returnVal2.Value;  //<-- just orphan code for debugging.  
        }
    }
    catch (Exception e)
    {
        await _logService.AddLogAsync(e, $"Error running SP:", "spLongRunningProcess");
    }
    return ro;
}

В строке Conn, которую я указал (Asynchronous Processing = True)

Чтобы проверить, действительно ли она работает, я просто проверяю базу данных через другой процесс. Просто ищу то, что я пропустил.

Ответы [ 2 ]

3 голосов
/ 04 октября 2019

Вы должны await вызвать ExecuteSqlCommandAsync:

await _context.Database.ExecuteSqlCommandAsync(...).ConfigureAwait(false);

Когда выполняется оператор await, LongSPCallAsync() вернется, и вызывающий поток может продолжить делать что-то еще, покаКоманда SQL была выполнена, и остальная часть метода выполнена.

Вы можете не ожидать LongSPCallAsync(), но вам нужно ждать ExecuteSqlCommandAsync(), чтобы DbContext не был утилизирован докоманда закончилаКроме того, если вы не дождетесь ExecuteSqlCommandAsync(), вы не сможете перехватывать и регистрировать любые исключения, выданные из него.

0 голосов
/ 04 октября 2019

Если вы действительно:

  1. Не важно, будет ли хранимая процедура успешной или неудачной, и
  2. Не нужно возвращать данные из хранимой процедуры

Тогда

  • Поскольку команда все еще будет выполняться при выходе из метода, вы не можете использовать using. Но это не имеет значения, поскольку на самом деле вам не нужно располагать DbContext объект .

  • Поскольку вы не ожидаете его завершения, выне сможет увидеть, произошло ли какое-либо исключение, поэтому try / catch вам не поможет.

  • Поскольку вы не хотите результата (и можетев любом случае), нет смысла использовать переменную returnVal2.

Так что вы можете сжать метод до следующего:

public void LongSPCallAsync()
{
    new DbContext().Database.ExecuteSqlCommandAsync("EXEC [spLongRunningProcess]");
}

Конечно, вы можете просто использовать await здесь и не использовать await там, где вы звоните LongSPCallAsync(), если вам все еще нужна обработка ошибок и ведение журнала, которые у вас уже есть.

Кроме того, это может быть хорошимпрочитайте для вас: Огонь и забудь на ASP.NET

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...