AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Globale Thread function ?

Ein Thema von Blamaster · begonnen am 23. Mär 2010 · letzter Beitrag vom 27. Mär 2010
Antwort Antwort
Seite 1 von 2  1 2      
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#1

Globale Thread function ?

  Alt 23. Mär 2010, 12:07
Hi,

ist es möglich eine globale function oder procedure zu setzen, die in allen laufenden Threads aufgerufen wird ?

Problem ist folgendes. Idhttp ist in einem Thread. 3 Threads laufen momentan parallel und schreiben ihren Status in eine Listview. Wenn nun ein Thread seine Arbeit beendet löscht er seine Statuszeile aus der Listview.

Ich bräuchte nun ein Event oder einen functionsaufruf der den anderen beiden Threads signalisiert das ein eintrag der Listview gelöscht wurde und sie nun auf eine andere Zeile der Listview zugreifen müssen.

Meine erste Idee war eine globale Variable in den Threads die der Thread der seine Arbeit gerade beendet auf true setzt. Problem dabei ist nur welcher Thread setzt die Variable wieder zurück denn die anzahl der laufenden threads ist nicht auf 3 beschränkt sondern variabel.

Ich hoffe jemand hat eine Idee zur Lösung des Problems

Mfg Yannic
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Globale Thread function ?

  Alt 23. Mär 2010, 12:10
Da alle Threads syncronisiert auf die Listview zugreifen müssen kannst du für alle Threads die gleiche Methode verwenden und in dieser entscheidest du dann welche Zeile welcher Thread bekommt.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#3

Re: Globale Thread function ?

  Alt 23. Mär 2010, 13:05
Danke für die Antwort.

Ich sehe da aber gerade ein kleines problem.
Die Threads können ja nicht mit parametern syncen.

Momentan habe ich eine eigen Unit für die Threads. (ThreadUnit) und gesynct wird beispielsweise auf ThreadUnit.ShowStatus.

Die Show Status greift dann auf die privaten Variablen des Threads zurück.

Wenn ich die ShowStatus jetzt ins Main Form verschiebe und dann auch MainForm.ShowStatus synce kennt die MainForm.ShowStatus die private variablen des jeweiligen Threads doch garnicht, da ich sie nicht mit parametern übergeben kann oder ?

Mfg Yannic
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Globale Thread function ?

  Alt 23. Mär 2010, 13:11
Meinst du sowas: http://www.michael-puff.de/Developer...readDemo.shtml
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#5

Re: Globale Thread function ?

  Alt 23. Mär 2010, 14:06
Hi,

genau das war der Denkanstoß

Danke funktioniert jetzt

Mfg Yannic
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#6

Re: Globale Thread function ?

  Alt 25. Mär 2010, 11:12
Hi,

ich melde mich nochmal in diesem Thread, da das Problem hier im Prinzip noch reinpasst.

Problem ist folgendes. Ich starte von der Mainform aus x Threads nach folgendes Schema:

Delphi-Quellcode:

MainForm:

var
  IndyThread: TDownloadThread;

....

  IndyThread := TDownloadThread.Create(True);
  IndyThread.FreeOnTerminate := True;
  IndyThread.URL := LinkList.Items.Item[i].Caption;
  IndyThread.FilePath := DownloadPfad;
  IndyThread.RsUsername := frmOptions.edtRSUsername.Text;
  IndyThread.RsPassword := frmOptions.edtRSPassword.Text;
  IndyThread.Resume;

  IndyThread := TDownloadThread.Create(True);
  IndyThread.FreeOnTerminate := True;
  IndyThread.URL := LinkList.Items.Item[i].Caption;
  IndyThread.FilePath := DownloadPfad;
  IndyThread.RsUsername := frmOptions.edtRSUsername.Text;
  IndyThread.RsPassword := frmOptions.edtRSPassword.Text;
  IndyThread.Resume;

....
Der Grobe Aufbau des Threads:

Delphi-Quellcode:
unit ThreadUnit;

interface

uses
  Classes, SysUtils, Windows, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdException, ComCtrls;

var
  is_abort: Boolean;

type
  TWorkBeginEvent = procedure(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer) of object;
  TWorkEvent = procedure(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer) of object;
  TWorkEndEvent = procedure(ASender: TObject; AWorkMode: TWorkMode) of object;
  TDownloadThread = class(TThread)
  private
    { Private-Deklarationen }
    FURL: string;
    FID: string;
    FFMessage: string;
    FFilePath: string;
    FFileName: string;
    FWorkCountMax: Integer;
    FWorkCount: Integer;

    IdHTTPDownload: TIdHTTP;
    filestream: TFileStream;

    procedure ShowStatus;
    procedure ShowEnd;
    procedure Error;
    procedure Successful;
    procedure Abort;
    procedure FWorkBeginEvent(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer);
    procedure FWorkEvent(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer);
    procedure FWorkEndevent(ASender: TObject; AWorkMode: TWorkMode);
  public
    property URL: string read FURL write FURL;
    property FilePath: string read FFilePath write FFilePath;
  protected
    procedure Execute; override;
  end;

implementation

uses
  MainU, GlobalsU;


{ TDownloadThread }


procedure TDownloadThread.Execute;
begin
  IdHTTPDownload := TIdHTTP.Create(nil);
  is_abort := False;

  try

    IdHTTPDownload.OnWorkBegin := FWorkBeginEvent;
    IdHTTPDownload.OnWork := FWorkEvent;
    IdHTTPDownload.OnWorkEnd := FWorkEndevent;


    FFileName := SetFileName(FURL);
    FID := FFileName;

    filestream := TFileStream.Create(FFilePath + FFileName, fmCreate);

    try
      IdHTTPDownload.Get(FURL, filestream);
    except
      on E: Exception do
      begin
        FFMessage := E.message;
        Synchronize(Error);
      end;
    end;

  finally
    IdHTTPDownload.Free;
    filestream.Free;
  end;
end;


procedure TDownloadThread.FWorkBeginEvent(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer);
begin
  FWorkCountMax := AWorkCountMax;

  Synchronize(ShowStatus);
end;


procedure TDownloadThread.FWorkEvent(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer);
begin
  FWorkCount := AWorkCount;
 
  if is_abort then
    Synchronize(Abort); // Wenn is_abort dann Download abbrechen

  // Berechnen der Statuswerte


  Synchronize(ShowStatus);
end;


procedure TDownloadThread.FWorkEndevent(ASender: TObject; AWorkMode: TWorkMode);
begin
  if not is_abort then
  begin
    Synchronize(ShowEnd);
    Synchronize(Successful);
  end;
end;


procedure TDownloadThread.ShowStatus;
begin
  // Zugriff auf die Vcl der Mainform
end;


procedure TDownloadThread.Successful;
begin
  // Zugriff auf die Vcl der Mainform
end;

procedure TDownloadThread.ShowEnd;
begin
  // Zugriff auf die Vcl der Mainform
end;

procedure TDownloadThread.Error;
begin
  // Zugriff auf die Vcl der Mainform
end;

procedure TDownloadThread.Abort;
begin
  // Download abbrechen
  IdHTTPDownload.Disconnect;
  // Zugriff auf die Vcl der Mainform
end;


end.
Nun möchte ich die thrads abbrechen. Das mache ich momentan indem ich eine Globale variable is_abort in der Thread Unit definiert habe und alle Threads im OnWork prüfen ob is_abort true oder false ist.

Im Prinzip funktioniert das auch. Ist allerdings nicht sonderlich schön wie ich finde (TDownloadThread.Abort wird auch mehrmals aufgerfufen, bevor das Disconnect wirklich gegriffen hat.

Gibt es eine Möglichkeit das ganze nicht über eine Variable zu prüfen, sondern eine Procedure oder ein Event das ich von der Mainform aus aufrufen kann, welches dann in allen Threads aufgerufen wird ?

Mfg Yannic
  Mit Zitat antworten Zitat
Tryer

Registriert seit: 16. Aug 2003
200 Beiträge
 
#7

Re: Globale Thread function ?

  Alt 25. Mär 2010, 11:20
Nur eine Variable und immer wieder neue Instanzen darauf erzeugen die dann länger bestehen.. pfui.
Nimm eine odentliche Liste in der Du die Threads verwaltest, dann hast Du auch jederzeit Zugriff darauf.

Grüsse,
Dirk
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#8

Re: Globale Thread function ?

  Alt 25. Mär 2010, 11:36
Hi,

sorry für die Dumme Frage aber was verstehst du in diesem Fall unter einer Liste zum verwalten ?

Das wäre natürlich optimal wenn ich auf alle Instanzen zugreifen könnte.

Mfg Yannic
  Mit Zitat antworten Zitat
Tryer

Registriert seit: 16. Aug 2003
200 Beiträge
 
#9

Re: Globale Thread function ?

  Alt 25. Mär 2010, 11:44
Ein "array of TDownloadThread" oder eine TList, damit Du eine Referenz auf jeden Thread behältst. Das Array bzw. die Liste kannst Du dann durchlaufen und jeden Thread nach Belieben manipulieren. Deine Variable "IndyThread" zeigt ja immer nur auf die zuletzt erstellte Instanz.

Grüsse,
Dirk
  Mit Zitat antworten Zitat
Blamaster

Registriert seit: 20. Jul 2007
230 Beiträge
 
#10

Re: Globale Thread function ?

  Alt 27. Mär 2010, 21:20
Soweit funktioniert jetzt schonmal alles ganz gut. Danke dafür

Lässt sich noch irgendwie feststellen, ob threadarray[x] schon erzeugt wurde ?

Momentan fange ich das über eine try except ab, das scheint mir aber nicht das optimum zu sein.

Mfg Yannic
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz