|
You last visited: Today at 21:16
Advertisement
"Multithreading" mit Gui
Discussion on "Multithreading" mit Gui within the AutoIt forum part of the Coders Den category.
11/22/2010, 16:29
|
#1
|
elite*gold: 280
Join Date: May 2007
Posts: 2,818
Received Thanks: 3,483
|
"Multithreading" mit Gui
Da immer wieder leute fragen, ob es möglich ist mehrere funktionen nebeneinander her laufen zu lassen, und ich zu faul bin ein tutorial zu schreiben, hier mal ein kleiner beispiel code der allgemein immer funktionieren sollte:
PHP Code:
Func _Sleep($time, $action) If $first_loop Then Assign($action&"_number", Eval($action&"_number")+1, 2) ElseIf Eval($action&"_active") Then If Eval($action&"_current") = Eval($action&"_count") Then If Not IsDeclared($action&"_timer") Or Eval($action&"_timer")='x' Then Assign($action&"_timer", TimerInit(), 2) ElseIf TimerDiff(Eval($action&"_timer")) >= $time Then Assign($action&"_current", Mod(Eval($action&"_current")+1, Eval($action&"_number")), 2) Assign($action&"_timer", 'x', 2) EndIf EndIf EndIf Assign($action&"_count", Mod(Eval($action&"_count")+1, Eval($action&"_number")), 2) EndFunc
Func _Func($func, $action) If $first_loop Then Assign($action&"_number", Eval($action&"_number")+1, 2) ElseIf Eval($action&"_active") = True Then If Eval($action&"_current") = Eval($action&"_count") Then Execute($func) Assign($action&"_current", Mod(Eval($action&"_current")+1, Eval($action&"_number")), 2) EndIf EndIf Assign($action&"_count", Mod(Eval($action&"_count")+1, Eval($action&"_number")), 2) EndFunc
Func Activation($action, $control=-1, $start="Start", $stop="Stop") If Not IsDeclared($action&"_active") Or Eval($action&"_active") = False Then Assign($action&"_active", True, 2) If $control<>-1 Then GUICtrlSetData($control, $stop) Else Assign($action&"_active", False, 2) If $control<>-1 Then GUICtrlSetData($control, $start) EndIf Assign($action&"_count", 0, 2) Assign($action&"_current", 0, 2) EndFunc
da auch sleeps nutzbar sein sollen, ohne dabei das script zu blockieren, habe ich mir mal ein system ausgedacht, dass die zum jeweiligen "thread" gehörigen aktionen durchnummeriert, und so sleeps per timer einzeln steuern kann
hierbei handelt es sich natürlich nicht um echtes multithreading. alles läuft in einem thread, wird jedoch ohne jegliche script blockierungen "gleichzeitig" ausgeführt.
die activation funktion ist zuständig für das starten und stopen der "threads". habe mal gleich noch mit eingebaut, dass sie auch in der lage ist controls zu bearbeiten (zb button texte ändern auf start/stop).
bei den funktionen und sleeps steht $action für die jeweilige thread bezeichnung.
hier mal ein beispiel, wodurch das ganze hoffentlich klar wird:
PHP Code:
; WICHTIG $first_loop muss am anfang des scripts als global auf true gesetzt werden Global $first_loop = True
; Beliebiges gui GUICreate("Gui", 130, 100, Default, Default, Default, 8) $btn_1 = GUICtrlCreateButton("Func 1", 10, 10, 100) $btn_2 = GUICtrlCreateButton("Func 2", 10, 40, 100) $btn_n = GUICtrlCreateButton("Func n", 10, 70, 100) GUISetState()
While 1 ;GuiGetMsg abfrage Switch GUIGetMsg() Case -3 Exit Case $btn_1 ; "thread 1" starten/stoppen, und button 1 jeweils auf start bzw stop umschreiben Activation(1, $btn_1, "Start Func 1", "Stop Func 1") Case $btn_2 ; "thread 2" starten/stoppen, ohne ein umschreiben des buttons Activation(2) ;Case ... ; ... Case $btn_n ; "thread 3" starten/stoppen, und button 3 jeweils auf start bzw stop umschreiben Activation('n', $btn_n, "Start Func n", "Stop Func n") EndSwitch
;--- Hier einfach die funktionen hinpacken --- ; funktion 1: _Sleep(1000, 1) _Func('ConsoleWrite("Funktion 1")', 1) _Func('ConsoleWrite(@CRLF)', 1) ; funktion 2: _Sleep(2000, 2) _Func('ConsoleWrite("Funktion 2"&@CRLF)', 2) ; [...] ; function n _Sleep(4000, 'n') _Func('ConsoleWrite("Funktion n"&@CRLF)', 'n') ; WICHTIG! ; --- hier ende vom ersten schleifendurchlauf bestätigen --- $first_loop = False WEnd
wir man hierran erkennt, laufen die einzelnen "threads" in sich nacheinander ab, aber global nebeneinander her.
|
|
|
11/22/2010, 17:39
|
#2
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
|
Erklärt sich eigentlich von selbst, von daher muss ein Tut auch nich sein.
Man könnte vielleicht noch eine Funktion einfügen, um die einzelnen Sektionen zu überbrücken/aufzuteilen, ist aber eher Schnickschnack.
Vote 4 Sticky
|
|
|
11/22/2010, 17:57
|
#3
|
elite*gold: 0
Join Date: Jan 2010
Posts: 360
Received Thanks: 249
|
sowas ist meiner meinung nach mit autoit sinnlos.
"multithreading" braucht man nicht wirklich für das, was mit autoit möglich ist.
|
|
|
11/22/2010, 20:15
|
#4
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
|
Quote:
Originally Posted by ZeraPain
sowas ist meiner meinung nach mit autoit sinnlos.
"multithreading" braucht man nicht wirklich für das, was mit autoit möglich ist.
|
Ich sag mal einfach Doodle Jump und Musicplayer;D
|
|
|
11/22/2010, 20:19
|
#5
|
elite*gold: 0
Join Date: Jan 2010
Posts: 360
Received Thanks: 249
|
Doodle Jump -> sagt mir nix
Musicplayer -> bau ich dir auch ohne "multithreading"
|
|
|
11/23/2010, 16:17
|
#6
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
|
Quote:
Originally Posted by ZeraPain
Doodle Jump -> sagt mir nix
Musicplayer -> bau ich dir auch ohne "multithreading"
|
Will ich sehen, ohne dass dir nach 1 Lied der Replay-Button abschmiert ;D
|
|
|
11/23/2010, 16:54
|
#7
|
elite*gold: 0
Join Date: Jan 2010
Posts: 360
Received Thanks: 249
|
Quote:
Originally Posted by mipez
Will ich sehen, ohne dass dir nach 1 Lied der Replay-Button abschmiert ;D
|
könnte man noch stark verbessern aber als bsp sollte es mal reichen ;-)
Code:
#include <file.au3>
#include <array.au3>
#include <guilistview.au3>
#include <sound.au3>
Global $path = @ScriptDir
Global $playindex = -1, $playid
Global $timer, $musicinfo, $maxplay
Global $pause = False
Global $OLD_pos
$Form1 = GUICreate("Musicplayer", 450, 200)
$GUI_listview = GUICtrlCreateListView("Play|Filename|Title|Interpret|Duration", 10, 10, 430, 100)
$GUI_pre = GUICtrlCreateButton("<<", 10, 120, 50)
$GUI_next = GUICtrlCreateButton(">>", 60, 120, 50)
$GUI_play = GUICtrlCreateButton("Play", 120, 120, 50)
$GUI_stop = GUICtrlCreateButton("Stop", 170, 120, 50)
$GUI_pause = GUICtrlCreateButton("Pause", 230, 120, 50)
$DISP_pos = GUICtrlCreateLabel("00:00:00", 300, 120, 50)
$GUI_pos = GUICtrlCreateSlider(10, 150, 430, 20)
$array = _FileListToArray($path, "*mp3")
$maxplay = $array[0]
Dim $musicinfo[$maxplay + 1][5]
For $i = 1 To $maxplay
$info = _FileInfoExtended($path & "\" & $array[$i])
$infotime = StringSplit($info[1][21], ":")
$musicinfo[$i][0] = $array[$i] ;Filename
$musicinfo[$i][1] = $info[1][16] ;Interpret
$musicinfo[$i][2] = $info[1][10] ;Title
$musicinfo[$i][3] = $info[1][21] ;Duration
$musicinfo[$i][4] = ($infotime[1] * 3600 + $infotime[2] * 60 + $infotime[3]) * 1000 ;Duration in ms
GUICtrlCreateListViewItem("|" & $musicinfo[$i][0] & "|" & $musicinfo[$i][1] & "|" & $musicinfo[$i][2] & "|" & $musicinfo[$i][3], $GUI_listview)
Next
GUISetState()
While 1
Switch GUIGetMsg()
Case -3
Exit
Case $GUI_play
$name = _GUICtrlListView_GetItemText($GUI_listview, Int(ControlListView($Form1, "", $GUI_listview, "GetSelected")), 1)
$playindex = _ArraySearch($array, $name)
_play($playindex)
Case $GUI_stop
_stop()
Case $GUI_pause
_pause()
Case $GUI_next
_next()
Case $GUI_pre
_pre()
EndSwitch
If $playindex <> -1 Then
If TimerDiff($timer) > $musicinfo[$playindex][4] Then _next()
$sound_per = Int(TimerDiff($timer) / $musicinfo[$playindex][4] * 100)
If $sound_per <> GUICtrlRead($GUI_pos) Then GUICtrlSetData($GUI_pos, $sound_per)
If _SoundPos($playid) <> $OLD_pos Then
$OLD_pos = _SoundPos($playid)
GUICtrlSetData($DISP_pos, _SoundPos($playid))
EndIf
EndIf
WEnd
Func _play($vPlayindex)
_SoundStop($playid)
$playid = _SoundOpen($path & "\" & $array[$vPlayindex])
_playindex($vPlayindex)
_SoundPlay($playid, 0)
$timer = TimerInit()
EndFunc ;==>_play
Func _stop()
_SoundStop($playid)
EndFunc ;==>_stop
Func _pause()
If $pause = False Then
$pause = True
_SoundPause($playid)
GUICtrlSetData($GUI_pause, "Resume")
Else
$pause = False
_SoundResume($playid)
GUICtrlSetData($GUI_pause, "Pause")
EndIf
EndFunc ;==>_pause
Func _next()
If $playindex > $array[0] Then $playindex = 1
If $playindex <> -1 Then
$playindex += 1
_play($playindex)
EndIf
EndFunc ;==>_next
Func _pre()
If $playindex > $array[0] Then $playindex = 1
If $playindex <> -1 Then
$playindex -= 1
_play($playindex)
EndIf
EndFunc ;==>_pre
Func _playindex($iPlay)
For $i = 0 To $maxplay - 1
If $i <> $iPlay - 1 Then
_GUICtrlListView_SetItemText($GUI_listview, $i, "")
Else
_GUICtrlListView_SetItemText($GUI_listview, $i, ">")
EndIf
Next
EndFunc ;==>_playindex
Func _FileInfoExtended($FolderOrFile)
If Not FileExists($FolderOrFile) Then Return SetError(1)
Local $objShell = ObjCreate("Shell.Application")
Local $arrHeaders[34], $Type = 'F'
If StringInStr(FileGetAttrib($FolderOrFile), 'D') Then
Local $objFolder = $objShell.Namespace($FolderOrFile)
$Type = 'D'
Else
Local $objFSO = ObjCreate("Scripting.FileSystemObject")
Local $objFile = $objFSO.GetFile($FolderOrFile)
Local $FileName = $objFSO.GetFileName($objFile)
Local $objFolder = $objShell.Namespace($objFSO.GetParentFolderName($objFile))
EndIf
Local $arRet[1][34]
For $i = 0 To 33
$arrHeaders[$i] = $objFolder.GetDetailsOf($objFolder.Items, $i)
$arRet[0][$i] = $arrHeaders[$i]
Next
For $strFileName In $objFolder.Items
If $Type = 'F' And $objFolder.GetDetailsOf($strFileName, 0) <> $FileName Then ContinueLoop
ReDim $arRet[UBound($arRet) + 1][34]
For $i = 0 To 33
$arRet[UBound($arRet) - 1][$i] = $objFolder.GetDetailsOf($strFileName, $i)
Next
Next
Return $arRet
EndFunc ;==>_FileInfoExtended
|
|
|
11/23/2010, 18:41
|
#8
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
|
Replay bedeutet, dass im Lied1 zu einem festgelegten Zeitpunkt entweder Lied1 oder Lied2 eingespielt wird. Zeitpunkt wird durch das Lied selbst festgelegt.
Aber geht sehr ins OT.
Anderes Beispiel: Downloader ;D
|
|
|
11/23/2010, 19:15
|
#9
|
elite*gold: 0
Join Date: Jan 2010
Posts: 360
Received Thanks: 249
|
Quote:
Originally Posted by mipez
Replay bedeutet, dass im Lied1 zu einem festgelegten Zeitpunkt entweder Lied1 oder Lied2 eingespielt wird. Zeitpunkt wird durch das Lied selbst festgelegt.
Aber geht sehr ins OT.
Anderes Beispiel: Downloader ;D
|
das mit dem song einspielen kriegt man auch hin.
man kann ja 2 songs parallel laufen lassen. (müsste man nur mehr playid's erstellen)
Downloader.. was genau meinst du jetzt damit?^^
einfach irgendeine datei herunterladen oder wie?
soll ich dir hier jetzt für jedes beispiel was coden ? xD
|
|
|
11/24/2010, 17:27
|
#10
|
elite*gold: 2
Join Date: Mar 2008
Posts: 1,778
Received Thanks: 1,222
|
Downloader?
Pseudocode:
Code:
InetGet(***)
;Alles was man zeitgleich machen will hier runter
|
|
|
11/24/2010, 19:24
|
#11
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
|
Quote:
Originally Posted by pinguin94
Downloader?
Pseudocode:
Code:
InetGet(***)
;Alles was man zeitgleich machen will hier runter
|
InetGet lässt sich doch nur 1x parallel ausführen (bei mehr als 1x lädts bei mir nix, ja Parameter wurden richtig bestimmt xD) oô
|
|
|
11/24/2010, 22:50
|
#12
|
elite*gold: 2
Join Date: Mar 2008
Posts: 1,778
Received Thanks: 1,222
|
Ach so meinst du das.
Notfalls InetGet auslagern auf andere Scripte?
|
|
|
11/25/2010, 18:49
|
#13
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
|
Quote:
Originally Posted by pinguin94
Ach so meinst du das.
Notfalls InetGet auslagern auf andere Scripte?
|
*hust* 16 Scripte am Laufen? *hust* xD
Naja, vllt bringts mit AutoIt nich allzuviel, aber das Prinzip lässt sich wunderbar auf Java übertragen
|
|
|
11/25/2010, 23:15
|
#14
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
|
java hat meines wissens sowieso multi threading o.ô
|
|
|
11/26/2010, 15:48
|
#15
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
|
Quote:
Originally Posted by MrSm!th
java hat meines wissens sowieso multi threading o.ô
|
Hab das erst seit knapp 2h Arbeitsstunden am Laufen... bis jetzt is mir dazu noch nix aufgefallen (wird alles nacheinander abgearbeitet)...
|
|
|
All times are GMT +2. The time now is 21:16.
|
|