AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Synchronize mit Argumenten

Ein Thema von Viktorii · begonnen am 9. Feb 2011 · letzter Beitrag vom 10. Aug 2011
Antwort Antwort
Seite 1 von 2  1 2   
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#1

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 09:36
Ich steh immer noch auf dem Schlauch. Habe den Zugriff mit eine CS geschützt.

In dieser CS übertrage ich meine Daten an eine TQueue (Das erste mal dass ich mit Generics gearbeitet habe ) damit die Blockierung auf ein zeitliches Minimum begrenzt bleibt. Allerdings blockiert das Abarbeiten der Queue die Funktion und es gehen immer noch Werte 'verloren'.
Delphi-Quellcode:
type
  TValueQueue = TQueue<Integer>;

  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FMyThread: TMyThread;
    FValueQueue: TValueQueue;
    procedure progress(value: Integer);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Clear;
  FValueQueue := TValueQueue.Create;
  FMyThread := TMyThread.Create(true);
  FMyThread.Progress := progress;
  FMyThread.Resume;
end;

procedure TForm1.progress(value: Integer);
begin
  FMyThread.SyncCS.Enter;
  FValueQueue.Enqueue(value);
  FMyThread.SyncCS.Leave;

  while FValueQueue.Count > 0 do
  begin
    Memo1.Lines.Add('Value: ' + IntToStr(FValueQueue.Dequeue));
    sleep(500);
  end;
end;
Delphi-Quellcode:
type
  TProgress = procedure(Value: integer) of object;

type
  TMyThread = class(TThread)
  private
    FValue: Integer;
    FProgress: TProgress;
    FSyncCS: TCriticalSection;
    procedure SyncProgress;
  protected
    procedure Execute; override;
  public
    property Progress: TProgress write FProgress;
    property SyncCS: TCriticalSection read FSyncCS;

  end;

implementation

uses
  Windows, SysUtils;
{ TMyThread }

procedure TMyThread.Execute;
var
  i: Integer;
begin
  FSyncCS := TCriticalSection.Create;
  for i := 1 to 10 do
  begin
    FSyncCS.Enter;
    FValue := i;
    FSyncCS.Leave;

    Queue(SyncProgress);
    sleep(200);
  end;
  //if assigned(FSyncCS) then
  // FreeAndNil(FSyncCS);
end;

procedure TMyThread.SyncProgress;
begin
  FProgress(FValue);
end;
Wie mache ich es richtig(er)?
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#2

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 10:28
!!! OFF TOPIC !!!

Ist ja echt frustrierend RAD heißt doch Rapid Application Development. Und es heißt doch immer mit Delphi geht alles immer so einfach im Gegensatz zu cpp. Ich habe ein Embedded Projekt mit Qt geschrieben und dachte mir ich versuche jetzt mal ob ich bei Qt auch dieses Problem habe....

Und siehe da, alles ganz einfach. Keine zusätzlichen privaten Felder in denen die zu übergebenden Werte stehen, keine zusätzlichen CS, keine zusätzlichen Methoden, keine Generic Queue oder was weiß ich für Tricksereien und im Gegensatz zu meiner Lösung bei Delphi funktioniert diese Qt Lösung (auf Anhieb nach 10 min)

Code:
class MainWindow : public QMainWindow
{
    Q_OBJECT

   public:
      explicit MainWindow(QWidget *parent = 0);
      ~MainWindow();

   private slots:
      void on_pushButton_clicked();
      void onProgress(qint32);

   private:
      Ui::MainWindow *ui;
};


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
   MyThread *myThread;

   myThread = new MyThread(this);

   connect(myThread,   SIGNAL(progress(qint32)),
         this,      SLOT(onProgress(qint32)));

   myThread->start();
}

void MainWindow::onProgress(qint32 value)
{
   ui->plainTextEdit->appendHtml("Value: " + QString::number(value));
   Sleep(500);
   qDebug() << QThread::currentThreadId() << "MainWindow::onProgress - Value:" << QString::number(value);
}
Code:
class MyThread : public QThread
{
    Q_OBJECT
   public:
      explicit MyThread(QObject *parent = 0);

   signals:
      void progress(qint32 value);

   public slots:

   protected:
      void run();

};


#include "MyThread.h"
#include <windows.h>
#include <QDebug>

MyThread::MyThread(QObject *parent) :
    QThread(parent)
{
}

void MyThread::run()
{
   for(qint32 i = 1; i <= 10; i++)
   {
      emit progress(i);
      Sleep(200);
      qDebug() << QThread::currentThreadId() << "MyThread::run() - Value:" << QString::number(i);
   }
   qDebug() << QThread::currentThreadId() << "Fertig";
}

Zitat:
0x14e8 MyThread::run() - Value: "1"
0x14e8 MyThread::run() - Value: "2"
0x13b4 MainWindow:nProgress - Value: "1"
0x14e8 MyThread::run() - Value: "3"
0x14e8 MyThread::run() - Value: "4"
0x13b4 MainWindow:nProgress - Value: "2"
0x14e8 MyThread::run() - Value: "5"
0x14e8 MyThread::run() - Value: "6"
0x14e8 MyThread::run() - Value: "7"
0x13b4 MainWindow:nProgress - Value: "3"
0x14e8 MyThread::run() - Value: "8"
0x14e8 MyThread::run() - Value: "9"
0x14e8 MyThread::run() - Value: "10"
0x14e8 Fertig
0x13b4 MainWindow:nProgress - Value: "4"
0x13b4 MainWindow:nProgress - Value: "5"
0x13b4 MainWindow:nProgress - Value: "6"
0x13b4 MainWindow:nProgress - Value: "7"
0x13b4 MainWindow:nProgress - Value: "8"
0x13b4 MainWindow:nProgress - Value: "9"
0x13b4 MainWindow:nProgress - Value: "10"
So, das musste mal raus. Jetzt gehts mir besser

Und wie mache ich es jetzt richtig in Delphi (siehe #25)?

Geändert von Viktorii (11. Feb 2011 um 10:31 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.531 Beiträge
 
Delphi 12 Athens
 
#3

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 11:23
Du übergibst da aber den Wert direkt an den Thread, bzw du gibst jedem Thread eine Kopie, so daß alle Threads ihre eigenen Werte haben.

In diesen Delphibeispielen nutzt du eine externe Variable für alle Threads.

> Äpfel und Birnen
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#4

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 11:27
@himitsu
und wie übergebe ich Delphi eine Kopie per Queue?
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.750 Beiträge
 
Delphi 12 Athens
 
#5

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 12:10
Sir Rufo hat ja bereits auf den Artikel in meinem Blog verwiesen, der den Aufruf von Synchronize mit einer Anonymen Methode zeigt. Natürlich kann man dieses Verfahren 1:1 auch auf Queue anwenden (habe ich auch erwähnt).

Allerdings muss man dann aufpassen (habe ich am Ende des Artikels auch drauf hingewiesen), daß der Thread sich nicht bereits beendet bevor die Queues alle abgearbeitet wurden. Ansonsten gehen die letzten Einträge nämlich verloren (gilt aber für alle Implementationen, die Queue benutzen).

Der Vorteil der Anonymen Methode ist einfach, daß man sich um die Kapselung des Parameters keine Gedanken mehr machen muss - das erledigt der Compiler. Das ganze Brimborium mit der TValueQueue ist damit völlig überflüssig.

Ach ja: Sollte jemand Probleme haben, den Artikel zu vestehen, da er auf Englisch verfasst ist, könnte ich mich vielleicht dazu durchringen, eine Deutsche Fassung hier an geeigneter Stelle (wo?) bereitzustellen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#6

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 13:39
Also ich bekomme es mit queue nicht hin.

Wie muss mein Code von #16 oder #26 abgeändert werden damit das funktioniert?

Könnte den korrekten code jemand evtl. posten? Wäre sehr dankbar!
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#7

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 14:05
Danke Uwe, ich hoffe ich habe es richtig verstanden:
Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;



type
  TProgress = procedure(const Value: integer) of object;

type
  TMyThread = class(TThread)
  private
    FValue: Integer;
    FProgress: TProgress;
    procedure SyncProgress(Value:Integer);
  protected
    procedure Execute; override;
  public
    property Progress: TProgress write FProgress;

  end;
  TForm2 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    FMyThread: TMyThread;
    procedure progress(const value: Integer);
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TMyThread.Execute;
var
  i: Integer;
begin
  for i := 1 to 10 do
  begin
    FValue := i;
    SyncProgress(i);
    sleep(200);
    OutputDebugString(PWideChar('FValue: ' + IntToStr(FValue)));
  end;
end;

procedure TMyThread.SyncProgress(Value:Integer);
begin
    Queue(
    Procedure
      begin
          FProgress(Value);
      end
    );
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  Memo1.Clear;
  FMyThread := TMyThread.Create(true);
  FMyThread.Progress := progress;
  FMyThread.Resume;
end;

procedure TForm2.progress(const value: Integer);
begin
  Memo1.Lines.Add('Value: ' + IntToStr(value));
  sleep(500);
end;
end.
Korrekturvorschläge willkommen....
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 16:14
(Das erste mal dass ich mit Generics gearbeitet habe )


Seit wann kann Delphi 5 mit Generics umgehen?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.750 Beiträge
 
Delphi 12 Athens
 
#9

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 16:22
(Das erste mal dass ich mit Generics gearbeitet habe )


Seit wann kann Delphi 5 mit Generics umgehen?
Und TThread.Queue gab's damals auch noch nicht...
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#10

AW: Synchronize mit Argumenten

  Alt 11. Feb 2011, 17:49
Also wie das Delphi 5 dahinkommt kann ich mir auch nicht erklären

Hab jetzt mittlerweile auch Delphi XE. Sorry für die Verwirrung.


Was den Code angeht: Kann sein dass ich da einen Bug eingebaut habe. War ein wenig zwischen Tür und Angel getestet.

Wie es aussieht habe ich vor Montag kein Delphi zur Verfügung. Werde es spätestens dann testen.

Schönes Wochenende an alle,
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 03:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz