Метод Post
пытается синхронно опубликовать элемент и возвращает true
или false
, в зависимости от того, принял ли элемент блок или нет. Причины не принимать элемент:
- Блок помечается как завершенный (путем вызова его метода
Complete
). - Блок завершен, успешно или неуспешно (его
Completion.IsCompleted
свойство возвращает true
). - Блок имеет ограниченную емкость (опция
BoundedCapacity != -1
), и его буфер в настоящее время заполнен.
Метод SendAsync
пытается опубликовать элемент асинхронно и возвращает Task<bool>
. Эта задача всегда будет завершена, если только блок не имеет ограниченной емкости, его буфер в настоящее время заполнен, и он в настоящее время не завершен или не отмечен как завершенный. Это единственный случай, когда SendAsync
будет вести себя асинхронно. После ожидания задачи результат задачи bool
указывает, принял ли блок элемент или нет. Причины не принимать элемент:
- Блок был помечен как завершенный либо до вызова
SendAsync
, либо во время ожидания. - Блок был завершен либо до вызова
SendAsync
, или во время ожидания в результате исключения, или потому что был вызван его метод Fault
.
Итак, разница между Post
и SendAsync
это точка (3). Они ведут себя по-другому в случае блока ограниченной емкости с полным буфером. В этом случае Post
немедленно отклоняет элемент, в то время как SendAsync
примет его асинхронно, когда в буфере снова появится свободное место.
В большинстве случаев поведение SendAsync
является желательным. Использование Post
вместо SendAsync
может рассматриваться как ожидаемая ошибка, когда спустя некоторое время блок переконфигурируется как ограниченный, чтобы решить недавно обнаруженные проблемы, связанные с чрезмерным использованием памяти.
Рекомендуется не отклонять возвращаемое значение обоих методов, потому что возвращаемое значение false
в большинстве случаев указывает на ошибку. очень редко можно ожидать и быть готовым обработать результат false
. Некоторые идеи:
if (!block.Post(item)) throw new InvalidOperationException();
if (!await block.SendAsync(item)) throw new InvalidOperationException();
var accepted = block.Post(item); Debug.Assert(accepted);
var accepted = await block.SendAsync(item); Debug.Assert(accepted);