(Как примечание: ваш NewBulk
метод должен вернуть Task
, иначе его вызывающие не могут ожидать его завершения - важно избегать кода, который запускает "запустить и забыть" asyn c logi c потому что становится невозможным безопасно очистить после завершения асинхронного c (или правильно перехватить ошибки) - единственное исключение - обработчики событий в WinForms и WPF - и это потому, что их контексты синхронизации будут правильно обрабатываться любые неудачные продолжения. - Кроме того, методы asyn c обычно должны иметь имена, заканчивающиеся суффиксом ...Async
.
В любом случае, ваша главная проблема в том, что ваш call-сайт для GetBulk
(который должен иметь имя GetBulkAsync
) неправильно объявляет ValueTuple
возвращение локального.
Вместо этого вы хотите:
class MyClass
{
private bool lastNewBulkResult;
internal async Task NewBulkAsync()
{
(ITestBulk testBulk, bool resultBulk) = await this.service.GetBulkAsync( 1, 2, "ggg" ); // Specify `ConfigureAwait` as appropriate too.
this.lastNewBulkResult = resultBulk;
}
}
Однако у этого кода есть проблемы: продолжение после GetBulkAsync
может потенциально работает в любом потоке - это означает, что состояние вашего MyClass
экземпляра (то есть его поля) видоизменяется в thread-unsa Fe образом. Решением этой проблемы является перепроектирование ваших классов, чтобы они полагались на неизменное состояние и представляли изменения в состоянии через параметры метода и возвращаемые значения (или асинхронные c результаты), что полностью исключает проблемы безопасности потоков.
Относительно смешивания ValueTuple
и await
:
Это утверждение:
(ITestBulk testBulk, bool resultBulk) = await this.service.GetBulkAsync( 1, 2, "ggg" );
Эквивалентно этому:
Task<(ITestBulk testBulk, bool resultBulk)> task = this.service.GetBulkAsync( 1, 2, "ggg" );
(ITestBulk testBulk, bool resultBulk) = await task;
И также эквивалентно этому:
Task<(ITestBulk testBulk, bool resultBulk)> task = this.service.GetBulkAsync( 1, 2, "ggg" );
(ITestBulk testBulk, bool resultBulk) tupleValue = await task;
ITestBulk testBulk = tupleValue.testBulk;
bool resultBulk = tupleValue.resultBulk;
Или это (используя var
для вывода типа объявления):
var task = this.service.GetBulkAsync( 1, 2, "ggg" );
var tupleValue = await task;
ITestBulk testBulk = tupleValue.testBulk;
bool resultBulk = tupleValue.resultBulk;
Или это:
var tupleValue = await this.service.GetBulkAsync( 1, 2, "ggg" );
ITestBulk testBulk = tupleValue.testBulk;
bool resultBulk = tupleValue.resultBulk;