![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Народ, пишу прогу для личного пользования, которая будет собирать музыку с музыкальных сервисов, но есть пара проблем, одна из них: Потоки
т.к никому не нравится, что программа при работе на какое-то время намертво зависает, пользователь привык: нажал на кнопку а программа тут же ему отвечает, без каких либо зависаний Создал два класса-потока (TThread) Один для аутентификации, Другой для работы с запросами к API одного из муз.сервисов Но при выполнении ошибок не происходит, код работает как надо, но.. Либо в потоке самой программы, либо я не знаю как еще, потому-что программа зависает секунды на 1.5-2, когда выполняется код Приводить весь модуль не буду, а только тот участок, который подвешивает программу во время выполнения кода К сожалению я почему-то не нашел здесь тега Спойлер, по-этому тема получилась немного громоздкой ![]() Код:
TZaycevRequest = class(TThread)
Client: TNetHTTPClient;
protected
procedure Execute; override;
function Request(Url: string): string;
end;
TZaycevAuthenticator = class(TThread)
Client: TNetHTTPClient;
protected
procedure Execute; override;
function Auth(): string;
end;
TZaycev = class(TObject)
constructor Create(AOwner: TComponent);
private
Authenticator: TZaycevAuthenticator;
Request: TZaycevRequest;
public
// Функции для работы с API Zaycev
// Авторизация
function Auth(): boolean;
var AccessToken: string; //Токен для работы с API
end;
implementation
function TZaycevAuthenticator.Auth: string;
var
hToken: string;
hResponse: TMemoryStream;
hStr: TStringList;
X: ISuperObject;
hMD5: TIdHashMessageDigest5;
hHash: string;
begin
// Получение Hello токена
hResponse := TMemoryStream.Create;
Client.Get(ZaycevAPIUrl + ZaycevHelloURL, hResponse);
hStr := TStringList.Create;
hStr.LoadFromStream(hResponse);
X := SO(hStr.Text);
hStr.Clear;
hResponse.Clear;
hToken := X.S['token'];
if hToken <> '' then
begin
//ShowMessage('hello token: ' + #13 + hToken);
hMD5 := TIdHashMessageDigest5.Create;
hHash := hMD5.HashStringAsHex(hToken + StaticKey).ToLower;
//ShowMessage('hToken: ' + hToken + #13 + 'hStaticKey: ' + StaticKey + #13 + 'hHash: ' + hHash);
if hHash <> '' then
begin
Client.Get(ZaycevAPIUrl + ZaycevAuthUrl + 'code=' + hToken +
'&hash=' + hHash, hResponse);
hStr.LoadFromStream(hResponse);
if hStr.Text <> '' then
begin
X := SO(hStr.Text);
Result := X.S['token'];
end;
end;
end;
end;
procedure TZaycevAuthenticator.Execute;
begin
inherited;
Client := TNetHTTPClient.Create(nil);
Client.Asynchronous := False;
end;
{ TZaycevRequest }
procedure TZaycevRequest.Execute;
begin
inherited;
Client := TNetHTTPClient.Create(nil);
Client.Asynchronous := False;
end;
function TZaycevRequest.Request(Url: string): string;
begin
if Url <> '' then
begin
//
end;
end;
{ TMyBaseComponent }
function TZaycev.Auth: boolean;
begin
Authenticator.Execute;
AccessToken := Authenticator.Auth(); //Авторизация
end;
constructor TZaycev.Create(AOwner: TComponent);
begin
Authenticator := TZaycevAuthenticator.Create(True);
Request := TZaycevRequest.Create(True);
Authenticator.Priority := tpLower;
Request.Priority := tpLower;
end; |
|
#2
|
||||
|
||||
|
Так метод Get нужно в потоке (внутри Execute) вызывать.
|
|
#3
|
|||
|
|||
|
Т.е только в Execute?
Процедура Auth, которая описана в потоке, не подойдет получается? |
|
#4
|
||||
|
||||
|
Поток реализуется именно методом execute, всё сотальное — в вызываемом (в твоем случае — главном) потоке.
|
|
#5
|
|||
|
|||
|
Самое главное, что Execute явно вызывать не надо!
|
|
#6
|
|||
|
|||
|
Можно пример?
Было бы неплохо, а то я все думал, но пока пришел к другому варианту, распишу его в ответном сообщении |
|
#7
|
||||
|
||||
|
Вот пример из c:\Program Files (x86)\Borland\Delphi7\Demos\Threads
|