На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Соблюдайте общие правила форума
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Указывайте точные версии Delphi и используемых сетевых библиотек.

Не приветствуется поднятие старых тем. Если ваш вопрос перекликается со старой темой, то для вопроса лучше создать новую тему, а старую указать в первом сообщении с описанием взаимосвязи.

Внимание:
попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Krid, user posted image Rouse_

Модераторы: Krid, Rouse_
  
> Datasnap и Thread , Передача файлов
    Здравствуйте. Есть код который отправляет файл на сервер по частям, а сервер его собирает все работает как надо. Но если этот код засунуть в поток то он отправляет не весь файл, подозреваю что поток посылает данные быстрее чем сервер их может обработать. Есть ли мысль по этому поводу или как организовать синхронизацию с классом.
    ExpandedWrap disabled
      var
        FS:TFileStream;
        MS:TMemoryStream;
        Buffer:TBytes;
        GUID:string;
        CountSection:int64;
        FullBufferSize:int64;
        BufferSize:int64;
        I:Integer;
      begin
      try
        fs:=TFileStream.Create('1.txt',fmOpenRead);
        FullBufferSize := FS.Size;
        CountSection := (FullBufferSize div GeneralForm.ClientSettings.max_buffer_size)+1;
        GUID := Client.ClientModule.ServerMethodsClient.AddNewFileTransfer(FullBufferSize);//<-Создаем кэш на сервере
        MS := TMemoryStream.Create;
        BufferSize := GeneralForm.ClientSettings.max_buffer_size;//<-максимальные размер буфера
        for I := 0 to CountSection do
          begin
            if FullBufferSize<=0 then Break;
            if FullBufferSize<BufferSize then
              BufferSize := FullBufferSize;
            Buffer := nil;
            SetLength(Buffer, BufferSize);
            FS.ReadBuffer(Buffer, BufferSize);
            MS.Clear;
            MS.WriteBuffer(Buffer, BufferSize);
            MS.Position := 0;
            Client.ClientModule.ServerMethodsClient.WriteFileOnServer(MS,GUID,BufferSize);//<-отправка буфера
            FullBufferSize:=FullBufferSize - GeneralForm.ClientSettings.max_buffer_size;
          end;
        client.ClientModule.ServerMethodsClient.SetEndFile(GUID);//говорим серверу что файл закончен
        MS.Destroy;
        FS.Destroy;
    Сообщение отредактировано: PIKACHU -
      может через ProcessMessages сделать и не парица?
        Разобрался, гиглвый файл уходит.
        переменные выводим в основной поток
        ExpandedWrap disabled
          constructor TMYT.Create(id: integer);
          begin
          inherited create(true);
          FreeOnTerminate := true;
          indexF:=id;
          WriteBlock := 0;
            lastEndPosition:=0;
            WriteBlockIn:=1;
            Sleep(50);
            GeneralForm.ClientSettings.max_buffer_size := 65000;
            fs:=TFileStream.Create('1.txt',fmOpenRead);
            FullBufferSize := FS.Size;
            CountSection := (FullBufferSize div GeneralForm.ClientSettings.max_buffer_size)+1;
            GUID := Client.ClientModule.ServerMethodsClient.AddNewFileTransfer(FullBufferSize);
            EventsForm.EventItem[indexF].ProgressBar.Max := CountSection;
            MS := TMemoryStream.Create;
            BufferSize := GeneralForm.ClientSettings.max_buffer_size;
            BB := 0;
            Resume;
          end;
           
          procedure TMYT.DoWork;
          label m1;
          begin
          try
              if (FullBufferSize<=0) then exit;
              m1:
                EventsForm.EventItem[indexF].ProgressPosition := BB;
                if FullBufferSize<BufferSize then
                  BufferSize := FullBufferSize;
                Buffer := nil;
                SetLength(Buffer, BufferSize);
                FS.Position := lastEndPosition;
                FS.ReadBuffer(Buffer, BufferSize);
                MS.Clear;
                MS.WriteBuffer(Buffer, BufferSize);
                MS.Position := 0;
                if Client.ClientModule.ServerMethodsClient.WriteFileOnServer(MS,GUID,BufferSize) then
                  lastEndPosition := FS.Position
                    else
                      goto m1;
                FullBufferSize:=FullBufferSize - GeneralForm.ClientSettings.max_buffer_size;
              inc(BB);
            if (FullBufferSize<=0) then
              begin
                client.ClientModule.ServerMethodsClient.SetEndFile(GUID);
                Terminate;
                MS.Free;
                FS.Free;
              end;
           
          except
          end;
          end;
           
          procedure TMYT.Execute;
            begin
              inherited;
              while not Terminated do
                begin
                  Sleep(10);
                  Synchronize(DoWork);
                end;
            end;

        Если будут какие нибудь замечания выслушаю.
        Сообщение отредактировано: PIKACHU -
          Цитата PIKACHU @
          Если будут какие нибудь замечания выслушаю.

          Главное замечание: это однопоточный код (гляньте справку на Synchronize и за счёт чего это дело работает).
            А смысл тут делать несколько потоков?
              Однопоточный в том смысле, что в один момент времени работает только ОДИН поток. Даже если в машине десятиядерник из новых экстремальных серий от Intel. Поэтому комбинация TThread + Synchronize однозначно вызывает тот самый вопрос: А смысл тут делать несколько потоков?
                Да я в курсе что при Synchronize основной поток не доступен, с потоками не очень силен может что то посоветуете. Писал 2 потока первый получает данные второй записывает и все равно без Synchronize не обошлось данные приходят не все, хотя по Ф8 все приходит.
                  Для начала - убрать всю работу с отображением прогресса (это плюшки, их можно сделать позже, через PostMessage).

                  Затем: всю логику по созданию объектов данных (типа TMemoryStream и т.п.) убрать из конструктора в метод Execute, т.к. Create работает в контексте потока-создателя (обычно - визуальный поток), а вот сам Execute - это именно новый поток.

                  Далее: что значит "данные приходят не все". Не хватает хвоста данных? Или в середине есть битые куски?
                    хвоста не хватает, причем всегда по разному. Есть мысль создать поток в нем и проводить все операции с данными, а в нем уже создать поток который будет передавать стримы, еще была идея внутри потока организовать экземпляр класса client соединятся с сервером и отправлять стримы. Как лучше.
                      Скорее всего, кто-то схлопывает коннект раньше времени (главный поток?), поэтому и получается, что по F8 всё ОК, а при работе обычный путём - хвост недопосылается.
                        В том то и дело что конект не закрывается, так как если начать ещё раз отправлять то опять же уходит часть без хвоста и всегда по разному в одной сессии
                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0438 ]   [ 17 queries used ]   [ Generated: 24.04.24, 01:50 GMT ]