Конференция "Сети" » повторное создание TMemoryStream
 
  • night_light © (26.05.09 17:58) [0]
    подскажите, пожалуйста, не могу разобраться,
    требуется в функции, которая периодически вызывается,
    заполнять переменную типа TMemoryStream, и потом её использовать, запуская метод Socket.SendStream,
    при этом сразу после ф-ии освобождать поток нельзя,
    т.к. действия в функции производятся в другом потоке,
    скрытом сокетным компонентом, если же поток создать однажды, то впоследствие программа ругается, что происходит ошибка при расширении памяти - информация, отправляемая в поток при каждом запуске ф-ии имеет разный размер. Нашёл выход - при запуске ф-ии каждый раз вызываю метод TMemoryStream.Create для вышеупомянутого потока, при этом не используя метод Free. При этом количество памяти, выделяемое для программы, не меняется, что странно. Вопрос, допустимо ли периодическое применение метода Create без использования метода Free, и почему при этом не возрастает используемая память?
  • Сергей М. © (26.05.09 19:41) [1]
    Ты справку к методу SendStream внимательно читал ?
  • Сергей М. © (26.05.09 19:49) [2]

    > заполнять переменную типа TMemoryStream


    Эта переменная заполняется единожды - в момент вызова конструктора TMemoryStream.Create


    > при этом сразу после ф-ии освобождать поток нельзя,
    > т.к. действия в функции производятся в другом потоке, скрытом сокетным компонентом


    Какой идиот тебе это сказал ?)


    > если же поток создать однажды,


    Его надо создавать столько раз, сколько успешных вызовов SendStream тобой произведено.


    > Вопрос, допустимо ли периодическое применение метода Create
    > без использования метода Free


    В случае с передачей созданного объекта этого класса параметром метода TCustomWinSocket.SendStream - да, допустимо. И не только допустимо, но обязательно, согласно документации к этому методу.
  • night_light © (27.05.09 02:27) [3]
    >> заполнять переменную типа TMemoryStream
    >Эта переменная заполняется единожды - в момент вызова конструктора >TMemoryStream.Create
    когда заполняется??.. А присвоение позже происходит, так?..
    детский сад какой-то...
    >> при этом сразу после ф-ии освобождать поток нельзя,0
    >Какой идиот тебе это сказал ?)
    уважаемый, вы на Delphi когда-нибудь программировали? если и да,
    то поток через сокеты не отправляли, это точно. Попробуйте освободить поток сразу после SendStream, удивитесь.
    >Его надо создавать столько раз, сколько успешных вызовов SendStream >тобой произведено
    где это написано?? приведи мне копию твоей чудесной документации? Я хоть почитаю, порадуюсь.
    у меня на Delphi 7 ничего даже подобного в справке нет.
    >В случае с передачей созданного объекта этого класса параметром метода >TCustomWinSocket.SendStream - да, допустимо. И не только допустимо, но >обязательно, согласно документации к этому методу.
    Вот за это спасибо! Даже не вериться, что ответ завершился конструктивно... Вот только бы ещё сказали, уважаемый, а какой документации речь?
  • brother © (27.05.09 07:41) [4]
    > какой документации речь?

    MSDN?
  • Вариант (27.05.09 08:39) [5]

    > night_light ©   (27.05.09 02:27) [3]


    > Вот за это спасибо! Даже не вериться, что ответ завершился
    > конструктивно... Вот только бы ещё сказали, уважаемый, а
    > какой документации речь?


    Delphi Help


    >  VCL Reference
    > TCustomWinSocket.SendStream
    >
    > Note: The Stream passed as a parameter to SendStream becomes
    > “owned” by the windows socket object.  The Windows socket
    > object frees the stream when it is finished with it.  Do
    > not attempt to free the stream after it has been passed
    > as a parameter
    .


    +  такой вариант документации -
    смотреть ScktComp.pas в исходниках дельфи  -> TCustomWinSocket.SendStream и далее по вызовам прочих функций (SendStreamPiece,DropStream)
  • Сергей М. © (27.05.09 08:51) [6]

    > детский сад какой-то


    Это не "детский сад", это суровая взрослая действительность)

    MyMemStreamVariable := TMemoryStream.Create;

    // это собственно "заполнение переменной"

    MyMemStreamVariable.WriteBuffer(..);

    // а вот ЭТО, если ты об этом, ни разу не "заполнение переменной" - это вызов метода записи в буфер !!!


    > Попробуйте освободить поток сразу после SendStream, удивитесь


    Не собираюсь даже пробовать - я хорошо знаком с логикой работы SendStream
    А вот тебе следует уяснить - метод SendStream работает с переданным ему параметром Stream-объектом  в том же самом треде, в котором этот метод был вызван.


    > где это написано?? приведи мне копию твоей чудесной документации?
    >  Я хоть почитаю, порадуюсь.


    Да пожалуйста).. Вот цитата из стандартной справки к методу TCustomWinSocket.SendStream:

    The Windows socket object frees the stream when it is finished with it

    О чем это говорит ?
    Это говорит о том, что если вызов метода SendStream завершился успешно, т.е. его выполнение не вызвало искл.ситуации, объект TCustomWinSocket становится полноправным "владельцем" : отныне он отвечает за своевременное и безусловное обязательное уничтожение stream-объекта, переданного параметром, после того как работа с этим стрим-объектом им будет завершена.
    Ну а раз права на "владение" стрим-объект отданы другому объекту, воспользоваться этим стрим-объектом повторно не удастся, что означает необходимость создания нового стрим-объекта перед очередным вызовом метода SendStream.
  • Bunsha (11.03.10 23:24) [7]
    Странная войнушка.
    На самом деле важны два факта:
    1). SendStream работает в контексте вызывающей нити.
    2). Socket является владельцем переданного потока.
    Вот и все объяснение.
    Сокет этот поток поимел и прибил (то что данные может еще не ушли к делу не относится). Посему пытаться работать с потоком после выхода из метода глупость! Нету его!
  • Плохиш © (12.03.10 12:07) [8]

    > night_light ©   (27.05.09 02:27) [3]


    > где это написано?? приведи мне копию твоей чудесной документации?
    >  Я хоть почитаю, порадуюсь.
    > у меня на Delphi 7 ничего даже подобного в справке нет.

    Пожалуйста, из справки к D7

    Hinweis: Eigentümer des Stream, der als Parameter an SendStream übergeben wird, wird das Windows-Socket-Objekt.  Das Windows-Socket-Objekt gibt den Stream nach erfolgter Verarbeitung frei.  Versuchen Sie nicht, den Stream, nachdem er als Parameter übergeben wurde, freizugeben.

  • Palladin © (12.03.10 12:35) [9]

    > Bunsha   (11.03.10 23:24) [7]
    > Плохиш ©   (12.03.10 12:07) [8]

    расслабтесь, это было давно, ночной светильник уже сюда не придет
  • Плохиш © (12.03.10 12:58) [10]

    > расслабтесь, это было давно

    дествительно... нафига было ветку поднимать? :-(
  • Анна (09.11.11 01:54) [11]
    Сергей М.

    Да пожалуйста).. Вот цитата из стандартной справки к методу TCustomWinSocket.SendStream:
    The Windows socket object frees the stream when it is finished with it

    О чем это говорит ?
    Это говорит о том, что если вызов метода SendStream завершился успешно, т.е. его выполнение не вызвало искл.ситуации, объект TCustomWinSocket становится полноправным "владельцем" : отныне он отвечает за своевременное и безусловное обязательное уничтожение stream-объекта, переданного параметром, после того как работа с этим стрим-объектом им будет завершена.
    Ну а раз права на "владение" стрим-объект отданы другому объекту, воспользоваться этим стрим-объектом повторно не удастся, что означает необходимость создания нового стрим-объекта перед очередным вызовом метода SendStream.

    Спасибо большое! вот только перечитав пару раз эти строки сообразилось, что не надо было всё пробовать удалить и освободить поток и что ошибка была не там, где искала..
  • brother © (09.11.11 04:31) [12]
    > расслабтесь, это было давно

    до сих пот еще кто-то напрягается)
 
Конференция "Сети" » повторное создание TMemoryStream
Есть новые Нет новых   [134436   +21][b:0][p:0.001]