Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.09.2010, 15:47   #1
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию Фоновая программа корректно работает только пол дня (использовал таймер)

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


Код:
TStatus = (ssDone, ssDownloading, ssWaiting, ssError);
var
  Form1: TForm1;
  Statuses: array of TStatus; //массив статусов для каждой композиции
  StatusesL: integer; //длина массива
  RunningThreads: integer = 0; //количество запущенный потоков (максимум 3 запущенный потока)
  cs: TCriticalSection;

...

procedure TForm1.FormCreate(Sender: TObject);
begin
  cs:=TCriticalSection.Create;
  StatusesL:=0;
  SetLength(Statuses, StatusesL);

  http.ReadTimeout:=10000;
  http.ConnectTimeout:=10000;

  CheckUrl(alt); //функция проверяет играющую композицию

  CheckSlot;
  //Form1.Show;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  StringGrid1.ColWidths[0]:=StringGrid1.ClientWidth-StringGrid1.ColWidths[1]-1;
end;

procedure TForm1.MP3Done(Sender: TObject; DownloadStatus: TDownloadStatus; msg: string);
var
  t: integer;
begin
  cs.Enter;
    t:=TMP3Saver(Sender).tag;
    if DownloadStatus=dsDone then
    begin
      Dec(RunningThreads);
      Statuses[t]:=ssDone;
      StringGrid1.Cells[1,t]:='Done';
    end
    else
    if DownloadStatus=dsStatus then
    begin
      StringGrid1.Cells[1,t]:=msg;
    end
    else
    if DownloadStatus=dsError then
    begin
      Dec(RunningThreads);
      Statuses[t]:=ssError;
      StringGrid1.Cells[1,t]:=msg;
    end;
  cs.Leave;
  CheckSlot;
end;

//Аналог функции Index для StringGrid'a
function TForm1.IndexInSG(s: string):integer;
var
  i: integer;
begin
  for i := 0 to StringGrid1.RowCount - 1 do
  begin
    if StringGrid1.Cells[0, i]=s then
    begin
      result:=i;
      exit
    end;
  end;
  result:=-1;
end;

procedure TForm1.CheckSlot;
var
  i: integer;
begin
  try
    cs.Enter;
    //если число запущенных потов больше 3, то выходим
    if RunningThreads>=MaxThreads then
      exit;
    //иначе находим первый ожидающий поток и создаём его
    for i := 0 to StatusesL - 1 do
    begin
      if Statuses[i]=ssWaiting then
      with TMP3Saver.Create(StringGrid1.Cells[0, i], ExtractFilePath(ParamStr(0))+Directory) do
      begin
        tag:=i;
        OnDone:=MP3Done;
        StringGrid1.Cells[1, i]:='Downloading...';
        Statuses[i]:=ssDownloading;
        inc(RunningThreads);
        Resume;
        break;
      end;
    end;
  finally
    cs.Leave;
  end;
end;

procedure TForm1.CheckUrl(a: string);
var
  s, mm, ss: string;
begin

  Timer1.Enabled:=false;
  try
    s := http.Get(a); //в S теперь строка вида '_songname = "Devision - Rage"   latency = "02:57"'
  except
    on e: exception do
    begin
      http.Free;
      http:=TIdHTTP.Create(nil);
      Timer1.Interval:=5000;
      //при ошибке говорим запустить эту функцию через 5 секунд
      Timer1.Enabled:=True;
      exit;
    end;
  end;

  mm:=s;
  s := StrParseToString(s, 'name = "', '"'); //в S теперь Devision - Rage

  if (IndexInSG(s) < 0) and (Length(s)>2) then //если строка корректна и её нет в СГ, то
  begin
    mm:=StrParseToString(mm, 'latency = "', '"'); //mm=02
    ss:=StrParseToString(mm, ':', ''); //ss=57
    Delete(mm, 3, 3);

    //увеличиваем массив и СГ
    inc(StatusesL);
    SetLength(Statuses, StatusesL);
    Statuses[StatusesL-1]:=ssWaiting;

    StringGrid1.Cells[0,StringGrid1.RowCount-1]:=s;
    StringGrid1.Cells[1,StringGrid1.RowCount-1]:='Waiting...';
    StringGrid1.RowCount:=StringGrid1.RowCount+1;

    //если есть слоты, то запускаем новый поток
    CheckSlot;

    //Устанавливаем и запускаем таймер
    Timer1.Interval:=(StrToInt(mm)*60+StrToInt(ss)+10)*1000;
    if Timer1.Interval<5000 then
      Timer1.Interval:=5000;
    if Timer1.Interval>6*60*1000 then
      Timer1.Interval:=6*60*1000;
    Timer1.Enabled:=true;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled:=false;
  CheckUrl(alt);
end;
Спустя несколько часов Timer.Enabled становится в False... (Добавил хинт по клику на форму, который показывает состояние таймера)
TwiX вне форума Ответить с цитированием
Старый 06.09.2010, 17:46   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Цитата:
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled:=false;
  CheckUrl(alt);
end;
checkUrl по логике дожен обязательно устанавливать timer1.enabled:=true;
теперь берем процедуру chackUrl и выкидываем оттуда все кроме работы с Timer1.enabled и ветвлений проверяем логику работы

Цитата:
Код:
var
  s, mm, ss: string;
begin

  Timer1.Enabled:=false;
  try
    s := http.Get(a); //в S теперь строка вида '_songname = "Devision - Rage"   latency = "02:57"'
  except
    on e: exception do
    begin
      Timer1.Enabled:=True;
      exit;
    end;
  end;

  if (IndexInSG(s) < 0) and (Length(s)>2) then //если строка корректна и её нет в СГ, то
  begin
    //Устанавливаем и запускаем таймер
    Timer1.Enabled:=true;
  end;
end;
видим что TTimer1.Enabled:=true; работает не всегда
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 06.09.2010 в 17:50.
evg_m на форуме Ответить с цитированием
Старый 06.09.2010, 17:57   #3
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

И правда... Забыл else приписать =)
Сам сидел и раза 4 вникал в эту функцию...
Спасибо большое. +
TwiX вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программа готова – пол дела, Главное защита от копирования!.. Игорь22 Общие вопросы Delphi 15 03.02.2015 14:47
Рекурсия. Не корректно работает прога Driver_09 Помощь студентам 0 23.12.2009 20:02
(паскаль) Обработка кв. матрицы. Программа есть. Не корректно работает функция SUM.. aslanbek999 Помощь студентам 3 02.06.2009 19:51
Программа работает не корректно Neymexa Общие вопросы C/C++ 5 24.12.2008 19:17