Entwickler-Ecke
Sonstiges (Delphi) - Thread beenden bei rekursivem Thread?
moelski - Sa 28.02.04 17:07
Titel: Thread beenden bei rekursivem Thread?
Moins !
Ich habe hier einen Codeschnipsel, der über
WNetEnumResource [
http://msdn.microsoft.com/library/en-us/wnet/wnet/enumerating_network_resources.asp] Freigaben im Netzwerk ausfindig macht. Das ganze läuft über einen Thread. Nun ist es so, das sich die entsprechende Funktion um WNetEnumResource immer wieder selber aufruft, bis sie alle Recourcen gefunden hat.
Leider kann ich dann aber nicht den Thread abbrechen. Hier mal ebend zwei Codeschnipsel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure TNetEnumThread.Execute; begin FreeOnTerminate := true; if terminated then exit; TreeNode:=nil; LoadNetNode(nil); end; |
Das macht der Thread ...
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TMainForm.CancelAutoClick(Sender: TObject); var Thread: TNetEnumThread; begin Thread.Terminate; end; |
Und so würde ich das ganze gerne beenden. Aber das klappt nicht. Und wie gesagt vermute ich, dass das an der Rekursion von LoadNetNode liegt.
Ich habe auch schon versucht, in dieser Procedure
Delphi-Quelltext
1:
| if terminated then exit; |
einzubauen, aber das funzt ebenfalls nicht.
Kann mir bitte mal jemand einen Tip geben, wie ich das Problem lösen kann?
Moderiert von
Peter Lustig: Code- durch Delphi-Tags ersetzt
rokdd - Sa 28.02.04 17:29
hallo,
habe ich recht verstanden das loadnetnode wieder die procedure aufruft? wenn ja würde ich folgendes machen:if not terminated then exit;
Wäre vielleicht nicht schlecht mal zu zeigen was loadnetnode macht...
Rokdd
moelski - Sa 28.02.04 17:39
Moin !
Ok, hier die Funktion LoadNetNode ...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122:
| procedure TNetEnumThread.LoadNetNode(NetNode: PNetResourceA); var hEnum : THandle; Count,BufSize, Usage: DWORD; NR,Buf: PNetResourceA; R: Integer; CurrentNode: TTreeNode; begin R:=WNetOpenEnum(RESOURCE_GLOBALNET,RESOURCETYPE_ANY,0,NetNode,hEnum); if R <> NO_ERROR then exit;
BufSize:=InitialSize; GetMem(Buf,BufSize); try while True do begin Count:=$FFFFFFFF; R:=WNetEnumResource(hEnum,Count, Buf, BufSize);
if R = ERROR_MORE_DATA then begin Count:=$FFFFFFFF; FreeMem(Buf); GetMem(Buf,BufSize); R:=WNetEnumResource(hEnum,Count, Buf, BufSize); end;
if R = ERROR_NO_MORE_ITEMS then Break; if R <> NO_ERROR then Abort; NR:=Buf; while Count > 0 do begin if NR.lpRemoteName <> nil then ChildNode:=StrPas(NR.lpRemoteName) else ChildNode:='';
ChildNode:=ChildNode+' DisplayType='; case NR.dwDisplayType of RESOURCEDISPLAYTYPE_DOMAIN: ChildNode:=ChildNode+'Domain'; RESOURCEDISPLAYTYPE_GENERIC: ChildNode:=ChildNode+'Generic'; RESOURCEDISPLAYTYPE_SERVER: ChildNode:=ChildNode+'Server'; RESOURCEDISPLAYTYPE_SHARE: ChildNode:=ChildNode+'Share'; RESOURCEDISPLAYTYPE_GROUP: ChildNode:=ChildNode+'Group'; RESOURCEDISPLAYTYPE_NETWORK: ChildNode:=ChildNode+'Network'; RESOURCEDISPLAYTYPE_ROOT: ChildNode:=ChildNode+'Root'; RESOURCEDISPLAYTYPE_SHAREADMIN: ChildNode:=ChildNode+'ShareAdmin'; RESOURCEDISPLAYTYPE_DIRECTORY: ChildNode:=ChildNode+'Directory'; RESOURCEDISPLAYTYPE_TREE: ChildNode:=ChildNode+'Tree'; RESOURCEDISPLAYTYPE_NDSCONTAINER: ChildNode:=ChildNode+'NDS Container'; else ChildNode:=ChildNode+'? ('+IntToStr(NR.dwDisplayType)+')'; end;
if NR.dwScope = RESOURCE_GLOBALNET then begin ChildNode:=ChildNode+' Usage=';
Usage:=NR.dwUsage; if (Usage and RESOURCEUSAGE_CONNECTABLE) <> 0 then ChildNode:=ChildNode+'Connectable;'; Usage:=Usage and not RESOURCEUSAGE_CONNECTABLE;
if (Usage and RESOURCEUSAGE_CONTAINER) <> 0 then ChildNode:=ChildNode+'Container;'; Usage:=Usage and not RESOURCEUSAGE_CONTAINER;
if (Usage and RESOURCEUSAGE_NOLOCALDEVICE) <> 0 then ChildNode:=ChildNode+'NoLocalDevice'; Usage:=Usage and not RESOURCEUSAGE_NOLOCALDEVICE;
if (Usage and RESOURCEUSAGE_SIBLING) <> 0 then ChildNode:=ChildNode+'Sibling'; Usage:=Usage and not RESOURCEUSAGE_SIBLING;
if (Usage and RESOURCEUSAGE_ATTACHED) <> 0 then ChildNode:=ChildNode+'Attached'; Usage:=Usage and not RESOURCEUSAGE_ATTACHED;
if (Usage and RESOURCEUSAGE_RESERVED) <> 0 then ChildNode:=ChildNode+'Reserved'; Usage:=Usage and not RESOURCEUSAGE_RESERVED;
if Usage <> 0 then ChildNode:=ChildNode+'? ('+IntToHex(Usage,8)+')'; end;
ChildNode:=ChildNode+' Type='; case NR.dwType of RESOURCETYPE_ANY: ChildNode:=ChildNode+'Any'; RESOURCETYPE_DISK: ChildNode:=ChildNode+'Disk'; RESOURCETYPE_PRINT: ChildNode:=ChildNode+'Print'; else ChildNode:=ChildNode+'?'; end;
ChildNode:=ChildNode+' Scope='; case NR.dwScope of RESOURCE_CONNECTED: ChildNode:=ChildNode+'Connected'; RESOURCE_GLOBALNET: ChildNode:=ChildNode+'Globalnet'; RESOURCE_REMEMBERED: ChildNode:=ChildNode+'Remembered'; else ChildNode:=ChildNode+'?'; end;
MainForm.ListBox2.Items.Add(childnode); if terminated then exit; LoadNetNode(NR);
INC(NR); DEC(Count); end; end; finally WNetCloseEnum(hEnum); FreeMem(Buf); end; end; |
Moderiert von
Peter Lustig: Code- durch Delphi-Tags ersetzt
Christian S. - Sa 28.02.04 17:49
Hallo, moelski!
Bitte benutze demnächst die Delphi-Tags. Durch die Delphi-Tags wird der Code mit Syntax-Highlighting angezeigt und ist somit sehr viel übersichtlicher.
Viele Dank!
Peter
rokdd - Sa 28.02.04 17:56
nun ich habe dir ja schon mein vorschlag gepostet(denn mit der if anweisung!). Statt den jetzt im excute einzusetzen würde ich den liebr in der procedure loadnetnode einsetzen....
rokdd
moelski - Sa 28.02.04 18:07
Moin !
@Peter: Sorry, werde ich beim nächsten Mal machen !
@rokdd: Wenn ich:
Delphi-Quelltext
1:
| if not terminated then exit; |
nutze, dann stoppt die Procedure sofort nach dem ersten Aufruf. Tja und wenn ich:
Delphi-Quelltext
1:
| if terminated then exit; |
nehme, dann stop garnix.
Noch (jemand) eine Idee?
rokdd - Sa 28.02.04 18:11
ich meinte folgendes:
Delphi-Quelltext
1:
| if not termiated then loadnetnode; |
damit wird der rekuroive aufruf nur ausgeführt wenn der thread.terminated=false ist!
rokdd
Edit von rokdd: DelphiTags korrigiert!
moelski - Sa 28.02.04 18:20
Moins ..
@rokdd: Leider auch nicht. Ich vermute, das da irgendwas bei meinem:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TMainForm.CancelAutoClick(Sender: TObject); var Thread: TNetEnumThread; begin Thread.Terminate; end; |
nicht so ganz sauber läuft. Gibt es dabei etwas wichtiges zu beachten, oder sollte das so laufen?
rokdd - Sa 28.02.04 18:23
ah jetzt hats bei m9r klick gemacht:
du definierst einen boolean den du am anfang azf false setzt. statt non termoated nimmst du jetzt bool=false.
willst du den thread beenden. setzt du bool auf true, sodass die "schleife" erst beendet wird und dann setzt du terminate ein.
rokdd
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!