Редактировать
Оригинальный ответ ниже посвящен проблеме создания кода из-за чрезмерной жесткой связи. Тем не менее, рассматривая решение в целом, я бы не использовал только один большой буфер и не передавал его части таким образом. Вы подвергаете свой код переполнению буфера (и мы будем называть это проблемами "опустошения" буфера). Вместо этого я бы управлял массивом байтовых массивов, каждый из которых представляет собой отдельный буфер. Передаваемое смещение всегда равно 0, а размер всегда равен длине буфера. Любой плохой код, который пытается прочитать / записать части за пределами границ, будет перехвачен.
Оригинальный ответ
Вы связали класс с SocketAsyncEventArgs, где на самом деле все, что ему нужно - это функция для назначения буфера, измените SetBuffer на: -
public void SetBuffer(Action<byte[], int, int> fnSet)
{
for (int i = 0; i < free.Length; i++)
{
if (1 == Interlocked.CompareExchange(ref free[i], 0, 1))
{
fnSet(buffer, i * blocksize, blocksize);
return;
}
}
fnSet(new byte[blocksize], 0, blocksize);
}
Теперь вы можете вызвать из кода потребления что-то вроде этого: -
myMgr.SetBuffer((buf, offset, size) => myArgs.SetBuffer(buf, offset, size));
Я не уверен, что вывод типов достаточно умен, чтобы разрешить типы buf, offset, size
в этом случае. Если нет, вам придется поместить типы в список аргументов: -
myMgr.SetBuffer((byte[] buf, int offset, int size) => myArgs.SetBuffer(buf, offset, size));
Однако теперь ваш класс можно использовать для выделения буфера для всех требований, которые также используют шаблон byte [], int, int, который очень распространен.
Конечно, вам нужно отделить бесплатную операцию, но вот: -
public void FreeBuffer(byte[] buff, int offset)
{
if (buffer == buff)
free[offset / blocksize] = 1;
}
Это требует от вас вызова SetBuffer для EventArgs при использовании кода в случае SocketAsyncEventArgs
. Если вы обеспокоены тем, что этот подход уменьшает атомарность освобождения буфера и удаления его из использования сокетов, то подкласс этого настроенного менеджера буфера подкласс и включает SocketAsyncEventArgs
специальный код в подкласс.