Я хочу вернуть середину Func используемого блока. Должен ли я беспокоиться об утилизации до того, как пользователь запустит результат Func?
Пример кода:
private IDbContextTransaction _transaction;
public Func<Task> BeginTransaction()
{
Task lockDispose = CommitTransaction();
using (_transaction = _dbContext.Database.BeginTransaction())
{
return async() =>
{
await lockDispose;
};
Task.WaitAll(lockDispose); //This code is unreachable.
}
}
private async Task CommitTransaction()
{
_transaction.Commit();
await Task.CompletedTask;
}
Обратите внимание, что время выполнения результата Func зависит от пользователя этой службы.
Я проверил Этот вопрос и это не мой ответ.
Я хочу отложить удаление до тех пор, пока пользователь не решит выполнить функцию результата.
Не могли бы вы привести пример того, как вы собираетесь использовать метод BeginTransaction?
Я хотел достичь этих целей: 1. Никто не может совершить транзакцию дважды (поэтому я скрыл CommitTransaction) 2. Не заставляйте пользователя использовать блок с помощью (или использование одной строки) 3. Пользователь может делать что угодно с dbContext и несколькими saveChanges до совершение транзакции __ Также использование по умолчанию для моего случая находится в промежуточном программном обеспечении, до и после «ожидания следующего (контекста);»
Но я не мог достичь этих целей. Я вернул Транзакцию из сервиса, к сожалению.
Я не думаю, что предоставление пользователю возвращаемых значений Func<Task> имеет смысл или удобство. Если вы не хотите, чтобы они совершали транзакцию дважды, вы можете дать им Transaction фасад с CommitTransaction методом, который вызывает реальный базовый Transaction.CommitTransaction не более одного раза.





Поскольку вы хотите, чтобы ваш пользователь мог работать со связью между вызовами BeginTransaction и CommitTransaction, единственное, что вы можете сделать, — это вывести удаление за пределы этой области:
private IDbContextTransaction _transaction;
public Func<Task> BeginTransaction()
{
_transaction = _dbContext.Database.BeginTransaction()
return CommitTransaction;
}
private async Task CommitTransaction()
{
_transaction.Commit();
_transaction.Dispose();
await Task.CompletedTask;
}
// I advice you implement IDisposable fully, but
// this will do for the sake of demonstration
public void Dispose()
{
_transaction?.Dispose();
}
А затем где-то снаружи вам нужно будет сделать что-то вроде:
using (var obj = TheWayYouInitializeYourObject())
{
var commit = obj.BeginTransaction();
// DO WORK
await commit();
}
или
try
{
var commit = obj.BeginTransaction();
// DO WORK
await commit();
}
finally
{
obj.Dispose();
}
По сути, ваш using не может охватывать пробел, в котором работает ваш пользователь, поэтому им придется делать это самостоятельно.
Как правило, рекомендуется делать предметы, которые должны работать с одноразовыми предметами, также одноразовыми.
Сомневаюсь, что после вызова BeginTransaction() транзакция начнется. И после этого пользователь должен работать с dbContext. Я протестирую ваше решение и приду снова, чтобы обновить этот комментарий.
@FarhadGh Обновил ответ.
Когда функция будет возвращена, транзакция будет удалена, а задача внутри функции уже будет выполняться. Вероятно, это не то, что вы хотите, судя по именам ваших методов? Вам нужно более точно указать, чего вы пытаетесь достичь.