Поведение задач в процессе - PullRequest
0 голосов
/ 21 сентября 2019

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

Согласно тому, что я знаю о задачах, задача, которая запускается первой, говорит, что TaskA может работать параллельно сдругая задача, скажем, TaskB, но TaskB может завершить работу и выйти из своего потока, прежде чем TaskA завершит свою работу.Поэтому в моем коде я пытаюсь выполнить операцию, но сначала узнаю состояние задачи.Правда ли, что эта задача под названием TaskResult в моем коде будет выполнена до того, как будут выполняться предыдущие строки кодов, или я должен использовать Task.Wait(), если это то, что я хочу?

 public virtual async Task<OperationResult> DeleteAsync(Expression<Func<TEntity, bool>> expression)
        {
            Task TaskResult = await _DbContext.Set<TEntity>().RemoveRange(IEnumerable<TEntity>);
            if (TaskResult.Status == TaskStatus.RanToCompletion)
            {
                return new OperationResult()
                {
                    Message = "",
                    ReturnObject = null,
                    Status = OperationStatus.Deleted,
                    Succeeded = true
                };
            }
            if (TaskResult.Status == TaskStatus.Faulted)
            {
                return new OperationResult()
                {
                    Message = "",
                    ReturnObject = null,
                    Status = OperationStatus.UnknownError,
                    Succeeded = false
                };
            }

        }

1 Ответ

0 голосов
/ 21 сентября 2019

Ключевое слово await остановит выполнение вашего метода до завершения Task.После завершения await либо вернет результат Task, либо выдаст исключение, которое произошло внутри Task (если оно было).Таким образом, нет смысла проверять, не произошел ли сбой Task, если вы его уже ожидали, потому что, если бы он вышел из строя, await вызвал бы исключение.

Просто оберните его в try / catch block.

Но ваш код даже не скомпилируется, потому что:

  1. DbSet<T>.RemoveRange не возвращает Task, потому что он не 'на самом деле вообще не могу общаться с базой данных.Он просто удаляет записи в памяти.Вам нужно позвонить DbContext.SaveChangesAsync(), чтобы ваши изменения были зафиксированы.
  2. Вы на самом деле не передаете список объектов на RemoveRange.(Вы изменили этот код для этого примера?)
  3. Как только вы ожидаете Task, ключевое слово await возвращает результат этого Task, а не сам Task.

Вот пример того, как вы могли бы написать это:

public virtual async Task<OperationResult> DeleteAsync(Expression<Func<TEntity, bool>> expression) {

    _DbContext.Set<TEntity>().RemoveRange(somethinghere);

    try {
        //commit the changes
        var result = await _DbContext.SaveChangesAsync();

        //result will be an int (the number of records changed), not a Task

        //if we got this far, we succeeded
        return new OperationResult()
        {
            Message = "",
            ReturnObject = null,
            Status = OperationStatus.Deleted,
            Succeeded = true
        };
    } catch (Exception e) {

        return new OperationResult()
        {
            Message = "", //you can use e.Message here if you want
            ReturnObject = null,
            Status = OperationStatus.UnknownError,
            Succeeded = false
        };
    }
}

Обратите внимание, что вы можете просто написать:

await _DbContext.SaveChangesAsync();

Если вы не собираетесь использовать result.

...