StartThread()
Enviado: 30 Out 2020 17:22
Passando só para destacar que MultiThread no xHarbour não funciona. Se vc usa xHarbour, nem perca seu tempo tentando.
Olá meu amigo, consegue me mostrar como fez?juniorcamilo escreveu:ola amigos!
como não tem como o startThread() funcionar em xHarbour 1.2.3, fiz um recurso técnico! Fiz minha automação chamar minha própria automação passando parâmetro, ou seja, executou o sistema em segundo plano e faz oq eu pedir e não para a execução!
betovsp escreveu: Olá meu amigo, consegue me mostrar como fez?
Estou precisando disso também.
Código: Selecionar todos
procedure EXECUTEDOWNLOADTRAVA(net,mArq)
if Valtype(net) == "L"
if net == .t.
net := "net online"
else
net := "net offline"
endif
endif
if at(":",CLDADOS) == 0
ccomando := '"'+CURDRIVE()+':'+CLDADOS+EXENAME()+'"'+" EXECUTE$DownloadTrava('"+tira(net," ")+"','"+mArq+"')"
winexec(cComando,2)
else
MyRun('"'+CLDADOS+EXENAME()+'"'+" EXECUTE$DownloadTrava('"+net+"','"+mArq+"')")
endif
returnCódigo: Selecionar todos
FUNCTION Main(Envio)
*********************
if at("EXECUTE$",Envio) # 0
TRY
Private Funcao := substr(Envio,at("$",Envio)+1)
&Funcao.
CATCH e
bErro := .t.
DefError(e,.f.)
FINALLY
seguranca()
END
endif
*********************Código: Selecionar todos
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Estrutura para passar dados para a thread
struct ThreadData {
char* cUrl;
PHB_ITEM pArray;
int nIndex;
};
// Protótipo da função findTable
char* findTable(const char* response);
// Função para gravar mensagem no arquivo "arqResult.txt"
void writeToFile(const char* message, int nIndex) {
FILE *fp;
int retries = 10; // Número de tentativas
int delay = 100; // Tempo de espera em milissegundos
while (retries > 0) {
fp = fopen("arqResult.txt", "a");
if (fp) {
// Remover quebras de linha do message antes de escrever no arquivo
size_t len = strlen(message);
char *cleanedMessage = (char *)malloc((len + 1) * sizeof(char));
if (cleanedMessage) {
size_t j = 0;
size_t i;
for (i = 0; i < len; i++) {
if (message[i] != '\n' && message[i] != '\r') {
cleanedMessage[j++] = message[i];
}
}
cleanedMessage[j] = '\0';
// Escrever no arquivo com o índice e o valor em texto
fprintf(fp, "Index: %d Value: %s\n", nIndex, cleanedMessage);
// Liberar a memória alocada para cleanedMessage
free(cleanedMessage);
}
fclose(fp);
break; // Sai do loop se o arquivo foi aberto e escrito com sucesso
} else {
retries--;
Sleep(delay); // Espera antes de tentar novamente
}
}
if (retries == 0) {
printf("Não foi possível abrir o arquivo arqResult.txt após várias tentativas.\n");
}
}
// Função para encontrar a posição do primeiro <table> em uma string
char* findTable(const char* response) {
const char* tableTag = "<table";
char* tablePos = strstr(response, tableTag);
return tablePos ? strdup(tablePos) : NULL;
}
// Função executada pela thread para realizar a requisição HTTP
DWORD WINAPI HttpRequestThread(LPVOID lpParam) {
// Declarar todas as variáveis no início
struct ThreadData* data = (struct ThreadData*)lpParam;
char* cUrl = data->cUrl;
PHB_ITEM pArray = data->pArray;
int nIndex = data->nIndex;
HINTERNET hSession;
HINTERNET hConnect;
char buffer[4096];
DWORD bytesRead;
DWORD totalBytes = 0;
char* response = NULL;
PHB_ITEM pResponse;
char* tableContent = NULL;
// Abrir uma sessão de internet
hSession = InternetOpen("MyAgent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hSession) {
hConnect = InternetOpenUrl(hSession, cUrl, NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (hConnect) {
while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead != 0) {
response = (char*)realloc(response, totalBytes + bytesRead + 1);
memcpy(response + totalBytes, buffer, bytesRead);
totalBytes += bytesRead;
}
if (response) {
response[totalBytes] = '\0';
// Encontrar o conteúdo do primeiro <table> na resposta
tableContent = findTable(response);
if (tableContent) {
pResponse = hb_itemPutCL(NULL, tableContent, strlen(tableContent));
hb_arraySet(pArray, nIndex, pResponse);
hb_itemRelease(pResponse);
// Escrever resposta no arquivo
writeToFile(tableContent, nIndex);
free(tableContent);
} else {
// Caso não encontre <table>, escrever "URL nao processada"
char* message;
size_t msgLen = snprintf(NULL, 0, "01 URL nao processada: %s", cUrl) + 1;
message = (char*)malloc(msgLen);
snprintf(message, msgLen, "01 URL nao processada: %s", cUrl);
writeToFile(message, nIndex);
free(message);
}
free(response);
} else {
// Caso não tenha resposta, escrever "URL nao processada"
char* message;
size_t msgLen = snprintf(NULL, 0, "01 URL nao processada: %s", cUrl) + 1;
message = (char*)malloc(msgLen);
snprintf(message, msgLen, "01 URL nao processada: %s", cUrl);
writeToFile(message, nIndex);
free(message);
}
InternetCloseHandle(hConnect);
} else {
// Caso a conexão falhe, escrever "URL nao processada"
char* message;
size_t msgLen = snprintf(NULL, 0, "01 URL nao processada: %s", cUrl) + 1;
message = (char*)malloc(msgLen);
snprintf(message, msgLen, "01 URL nao processada: %s", cUrl);
writeToFile(message, nIndex);
free(message);
}
InternetCloseHandle(hSession);
} else {
// Caso a sessão falhe, escrever "URL nao processada"
char* message;
size_t msgLen = snprintf(NULL, 0, "01 URL nao processada: %s", cUrl) + 1;
message = (char*)malloc(msgLen);
snprintf(message, msgLen, "01 URL nao processada: %s", cUrl);
writeToFile(message, nIndex);
free(message);
}
free(data->cUrl);
free(data);
// Redefinindo tableContent para NULL após uso
tableContent = NULL;
return 0;
}
Código: Selecionar todos
EXTERNAL _StartThread, _WaitForSingleObject, _CloseHandle
FUNCTION Main()
LOCAL aUrls := { ;
"https://www.tcepi.tc.br/fiscalizado/situacao-das-prestacoes-de-contas/?type=municipais&ug=1449&ano=2024&mes=03",;
"https://www.tcepi.tc.br/fiscalizado/situacao-das-prestacoes-de-contas/?type=municipais&ug=1449&ano=2024&mes=01",;
"https://www.tcepi.tc.br/fiscalizado/situacao-das-prestacoes-de-contas/?type=municipais&ug=1449&ano=2024&mes=04",;
"https://www.tcepi.tc.br/fiscalizado/situacao-das-prestacoes-de-contas/?type=municipais&ug=1449&ano=2024&mes=05",;
"https://www.tcepi.tc.br/fiscalizado/situacao-das-prestacoes-de-contas/?type=municipais&ug=1449&ano=2024&mes=06",;
"https://www.tcepi.tc.br/fiscalizado/situacao-das-prestacoes-de-contas/?type=municipais&ug=1449&ano=2024&mes=02" ;
}
LOCAL aHandles := ARRAY(LEN(aUrls))
LOCAL i
// Iniciar as threads
FOR i := 1 TO LEN(aUrls)
aHandles[i] := _StartThread(aUrls[i])
NEXT
// Esperar que todas as threads terminem
FOR i := 1 TO LEN(aHandles)
_WaitForSingleObject(aHandles[i])
_CloseHandle(aHandles[i])
NEXT
? "Todas as threads terminaram."
RETURN NIL
PROCEDURE _StartThread(cUrl)
LOCAL hThread, nIndex
nIndex := 0 // Indice de exemplo, ajuste conforme necessário
hThread := hb_HbMkProc( cUrl, nIndex )
RETURN hThread
PROCEDURE _WaitForSingleObject(hThread)
LOCAL nResult
nResult := hb_HbMkWaitSingleObject( hThread )
RETURN nResult
PROCEDURE _CloseHandle(hThread)
hb_HbMkCloseHandle( hThread )
RETURN NIL