Синхронизация потоков...
От: neoFIRE Украина http://www.sikorskyy.com.ua/
Дата: 15.01.07 18:01
Оценка:
Добрый вечер!

Есть следующая функция обратного вызова, которая отрабатывает при получении данных сокетом:


private void _NET_DataReceived(IAsyncResult result)
    {
      NETClient client = (NETClient)result.AsyncState;

      try
      {
        int length = client.Socket.EndReceive(result);

        if (length == 0)
        {
          this._NET_DisconnectClient(client);
          this._NET_SynchronizeLv();
        }

        else
        {
          if (client.InBuffer == null)
          {
            client.InBuffer = new byte[length];

            Array.Copy(client.Buffer, 0, client.InBuffer, 0, length);
          }

          else
          {
            byte[] buffer = new byte[client.InBuffer.LongLength + length];

            Array.Copy(client.InBuffer, 0, buffer, 0, client.InBuffer.LongLength);
            Array.Copy(client.Buffer, 0, buffer, client.InBuffer.LongLength, length);
            client.InBuffer = buffer;
          }

          while (Commons.FindCommand(client.InBuffer, Commands.GS) != -1)
          {
            this._NET_ProcessCommand(client);
            client.InBuffer = Commons.DeleteCommand(client.InBuffer, Commands.GS);
          }
        }

        client.Buffer = new byte[1024];
        client.Socket.BeginReceive(client.Buffer, 0, client.Buffer.Length, SocketFlags.None,
          new AsyncCallback(_NET_DataReceived), client);
      }

      catch (SocketException se)
      {
        this._NET_DisconnectClient(client);
        this._NET_SynchronizeLv();
        this._UI_Msg(se.Message, ActionStates.Fault);
      }

      catch (Exception e)
      {
        this._NET_DisconnectClient(client);
        this._NET_SynchronizeLv();
        this._UI_Msg(e.Message, ActionStates.Fault);
      }
    }



Все почти хорошо. Но. Бывает, что данные от клиента приходят быстрее, чем успевает отработать цикл


while (Commons.FindCommand(client.InBuffer, Commands.GS) != -1)
          {
            this._NET_ProcessCommand(client);
            client.InBuffer = Commons.DeleteCommand(client.InBuffer, Commands.GS);
          }


и изменяется содержимое client.InBuffer. Понятно, что функция Common.DeleteCommand сразу вылетает.

Так вот вопрос: что нужно залочить (lock () ) в моем случае? Я разные комбинации перепробовал (вплоть до lock (this._clients на все тело функции)) — ничего не помогает.

Подскажите, пожалуйста, очень прошу!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.