Estive vendo como é simples utilizar threads com harbour. No entanto, quando fazia isto o formulário do sistema congelava e ás vezes até travava.
Aqui passo a estratégia que utilizei para sanar este problema. Neste exemplo a rotina principal apresenta uma barra de progresso enquanto duas
Threads geram o mapa do HD listando todos os arquivos da unidade C: e todos os arquivos da unidade D: em dois arquivos de texto.
Ao final de cada thread é apresentado o valor da variável inicio.
Primeiramente vamos ao código fonte do arquivo Main:
#include <hmg.ch>
#include "hbthread.ch"
memvar inicio // variavel acessivel dentro das threads
Function Main
Load Window Main
Main.Center
Main.Activate
Return
function iniciar()
inicio := 0
// Veja como a simples a chamada das threads
// Observe que as threads herdam os parametros da variavel memvar inicio
nThreadId := hb_ThreadStart( HB_THREAD_INHERIT_MEMVARS, @vthread() )
nThreadId2 := hb_ThreadStart( HB_THREAD_INHERIT_MEMVARS, @vthread2() )
do while (inicio <= 100)
Main.texto.value := str(inicio)
Main.bar.value:= inicio
Main.show() // Necessário para dar o refresh na tela... é o pulo do gato...
inicio = inicio + 2.5
inkey(.5)
enddo
Main.bar.value:= 100
msgbox("fim")
return
procedure vThread()
for ct:= 1 to 1
comando := "cmd /c dir c:\*.* /a/s > a.txt"
run &comando
next
msgbox("fim da thread 1 " + str(inicio))
return NIL
procedure vThread2()
comando := "cmd /c dir d:\*.* /a/s/on > b.txt"
run &comando
msgbox("fim da thread 2 " + str(inicio))
return NIL
Reparem na linha onde está Main.show(). Se você não colocar este comando a barra de progresso trava e somente é atualizada no final... Este é o pulo do gato!!!
O código fonte do formulário segue abaixo:
* HMG-IDE Form Designer Generated Code
* (c) Roberto Lopez - http://sites.google.com/site/hmgweb
DEFINE WINDOW TEMPLATE AT 196 , 331 WIDTH 550 HEIGHT 350 VIRTUAL WIDTH Nil VIRTUAL HEIGHT Nil TITLE "Exemplo de Thread em Harbour" ICON NIL MAIN CURSOR NIL ON INIT Nil ON RELEASE Nil ON INTERACTIVECLOSE Nil ON MOUSECLICK Nil ON MOUSEDRAG Nil ON MOUSEMOVE Nil ON SIZE Nil ON MAXIMIZE Nil ON MINIMIZE Nil ON PAINT Nil BACKCOLOR Nil NOTIFYICON NIL NOTIFYTOOLTIP NIL ON NOTIFYCLICK Nil ON GOTFOCUS Nil ON LOSTFOCUS Nil ON SCROLLUP Nil ON SCROLLDOWN Nil ON SCROLLLEFT Nil ON SCROLLRIGHT Nil ON HSCROLLBOX Nil ON VSCROLLBOX Nil
DEFINE PROGRESSBAR Bar
ROW 150
COL 50
WIDTH 450
HEIGHT 60
RANGEMIN 1
RANGEMAX 100
VALUE 0
TOOLTIP ""
HELPID Nil
VISIBLE .T.
SMOOTH .F.
VERTICAL .F.
BACKCOLOR NIL
FORECOLOR NIL
END PROGRESSBAR
DEFINE BUTTON Button_1
ROW 60
COL 70
WIDTH 100
HEIGHT 28
ACTION Iniciar()
CAPTION "Iniciar"
FONTNAME "Arial"
FONTSIZE 9
TOOLTIP ""
FONTBOLD .F.
FONTITALIC .F.
FONTUNDERLINE .F.
FONTSTRIKEOUT .F.
ONGOTFOCUS Nil
ONLOSTFOCUS Nil
HELPID Nil
FLAT .F.
TABSTOP .T.
VISIBLE .T.
TRANSPARENT .F.
MULTILINE .F.
PICTURE Nil
PICTALIGNMENT TOP
END BUTTON
DEFINE TEXTBOX texto
ROW 70
COL 320
WIDTH 120
HEIGHT 24
FONTNAME "Arial"
FONTSIZE 9
TOOLTIP ""
ONCHANGE Nil
ONGOTFOCUS Nil
ONLOSTFOCUS Nil
FONTBOLD .F.
FONTITALIC .F.
FONTUNDERLINE .F.
FONTSTRIKEOUT .F.
ONENTER Nil
HELPID Nil
TABSTOP .T.
VISIBLE .T.
READONLY .F.
RIGHTALIGN .F.
DISABLEDBACKCOLOR Nil
DISABLEDFONTCOLOR Nil
BACKCOLOR NIL
FONTCOLOR NIL
INPUTMASK Nil
FORMAT Nil
VALUE ""
END TEXTBOX
END WINDOW
Por padrão a minigui não compila o executável com a threads ativas. Para isto você deve habilitar este recurso na IDE, Gerenciador de Projeto, Aba configuração. Nesta aba configure o campo Multi-Thread para .T.
Saudações a todos!!