세션이 SendAsync를 할 때마다 버퍼를 생성하는 것이 아니라
미리 만들어 둔 큰 버퍼에 데이터를 쓰고 해당 데이터만큼을 사용할 수 있도록하는 클래스
public SendBuffer(int chunkSize)
{
_buffer = new byte[chunkSize];
}
public ArraySegment<byte> Open(int reserveSize)
{
if (FreeSize < reserveSize)
{
return null;
}
return new ArraySegment<byte>(_buffer, _usedSize, reserveSize);
}
public ArraySegment<byte> Close(int usedSize)
{
ArraySegment<byte> segment = new ArraySegment<byte>(_buffer, _usedSize, usedSize);
_usedSize += usedSize;
return segment;
}
생성 시 버퍼의 크기를 받아 버퍼를 만들어 둔다.
세션은 Open을 통해 미리 예상되는 데이터의 크기보다 크게 버퍼를 가져오고,
실제로 데이터를 입력한 만큼을 Close로 알려주어 해당 크기 만큼의 영역을 사용하지 않도록 한다.
public static ThreadLocal<SendBuffer> CurrentBuffer = new ThreadLocal<SendBuffer>(() => { return null; });
public static ArraySegment<byte> Open(int reserveSize)
{
if (CurrentBuffer.Value == null
|| CurrentBuffer.Value.FreeSize < reserveSize)
{
CurrentBuffer.Value = new SendBuffer(ChunkSize);
}
return CurrentBuffer.Value.Open(reserveSize);
}
public static ArraySegment<byte> Close(int usedSize)
{
return CurrentBuffer.Value.Close(usedSize);
}
SendBufferHelper 클래스는 TLS를 이용하여 세션 스레드마다 버퍼를 가질 수 있도록 함