Здравствуйте.
1)
Сейчас имеется приблизительно такой код обработки потока сокета в стиле APM:
| APM |
| public void ReadAsync()
{
try
{
if (_disposed)
{
return;
}
var syncObj = new SyncObjTcp {Stream = Stream, Received = new byte[4096]};
Stream.BeginRead(syncObj.Received, 0, 4096, OnBeginRead, syncObj);
}
catch(Exception ex)
{
Log.Write(ex);
}
}
private void OnBeginRead(IAsyncResult result)
{
if (_disposed)
{
return;
}
try
{
var dataLen = Stream.EndRead(result);
if (dataLen > 0)
{
var data = ((SyncObjTcp)result.AsyncState).Received.Take(dataLen).ToArray();
//1й вариант
HandleData(data);
ReadAsync();
//2й вариант
// ReadAsync();
// HandleData(data);
return;
}
if (dataLen == 0)
{
CloseFromRead();
}
}
catch(Exception ex)
{
//catch logic
}
}
|
| |
Метод HandleData может бы давольно емким, соотв. мы не будем вычитывать из сокета до тех пор пока не обработаем текущую порцию данных (1-вариант в коде);
2-й вариант (закоментированный фрагмент) асинхронный, т.е. как только мы вычитали данные, мы сразу же читаем новую порцию.
В связи с этим вопрос: если использовать 2-й вариант, возможет ли rc между обработкой данных, т.к. скорее всего это будут разные потоки, соотв. разные ядра и может получиться
так, что тот, кто раньше начал позже закончит, а это крайне не желательно в текущем приложении -- чтение и обработка данных в реальном времени.
(Это больше теоритический вопрос, поскольку я через блокирующую очерь разведу получение и обработку данных, но все равно даже подготовка данных для
блокирующей очереди может быть под rc)
2)Второй вариант это async, что-то вроде:
while (true)
{
int result = await stream.ReadAsync(buffer, 0, 4096, cancellationToken);
if (result == 0)
{
break
}
HandleData(buffer);
}
Вопрос: как сейчас грамотнее делать APM или async? Вроде async более понятен для чтения и этот код эквивалентен 1-ому варианту APM.
Правильно ли я понимаю, что в обоих случаях будет вызываться iocp-поток? Соотв. если у меня будет много подобных соединений, то и iocp-потоков
должно быть много.
Заранее благодарю.