2016-09-06 5 views
0

У меня есть приложение, написанное в Delphi с использованием TClientSocket, которое отправляет данные в другое приложение, написанное на C#. По многим причинам приложение C# работает медленно, блокируя приложение Delphi и не соблюдая тайм-аут, который я установил.TClientSocket в постоянном соединении Delphi

Мои Delphi приложение читает ответы, как это:

Sock.Socket.ReceiveText 

Это заставляет приложение ждать ответа. Но если я сделаю это вместо этого, приложение ожидает и уважает тайм-аут:

while not receiveData do 
begin 
    if Sock.Socket.ReceiveLength > 0 then 
    begin 
    receiveData := True; 
    end; 
    Inc(Cont); 
    Sleep(100); 

    if (Cont > 10) then 
    raise Exception.Create('Timeout'); 
end; 

Мой Delphi приложение отправляет два запроса. Первый раз, но C# все еще обрабатывает его. Затем приложение My Delphi отправляет второй запрос, и на этот раз C# отправляет ответ для первого запроса.

Будет ли второй запрос получать данные для первого запроса? Или, когда я перейду в Delphi, они перейдут информацию?

ответ

3

Как только ваш код Delphi истечет, он забывает о первом запросе, но ваш код C# этого не знает. Поскольку вы не удаляете соединение, второй запрос действительно получит данные ответа для первого запроса. Внедряя логику таймаута, а затем игнорируя причину таймаута, вы не синхронизируете свои два приложения друг с другом. Таким образом, либо используйте более длительный тайм-аут (или вообще нет тайм-аута), либо отключите соединение, если произойдет таймаут.

Что касается замораживания приложений Delphi, это должно произойти только в том случае, если вы используете компонент TClientSocket в режиме блокировки и выполняете чтение в контексте основного потока пользовательского интерфейса. Вы не должны использовать режим блокировки в основном потоке пользовательского интерфейса. Либо:

  1. Использование TClientSocket в неблокирующем режиме, делать все прочитанного в только OnRead случае, и не читать больше, чем ReceiveLength указывает.

  2. Используйте TClientSocket в режиме блокировки и выполняйте все ваши чтения в рабочем потоке, а затем передавайте основной поток пользовательского интерфейса только тогда, когда есть данные для его обработки (лучше было бы обрабатывать данные у рабочего поток и только синхронизация с основным потоком при создании обновлений пользовательского интерфейса).