Чтение из сокета -- APM vs async. Пару вопросов.
От: Sharov Россия  
Дата: 22.03.22 18:08
Оценка:
Здравствуйте.

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-потоков
должно быть много.

Заранее благодарю.
Кодом людям нужно помогать!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.