Component w Watku

0

Witam
Mam taki problem, że w pewnym wątku genereję tablicę danych bb[1..66] która chciałbym wyświetlić w postaci słupków w komponencie TChar. Do tej pory korzystałem z komponentu TChar który umieszcziłem na formie głownej. Jednak gdy dokonuje jakieś operacji w głównym wątku (zasymulowałem to w formie Sleep) to dane te są wyświetlane bardzo wolno. I tutaj moje pytanie, czy istnieje możliwość stworzenia komponentu TChar, który bedzie powiązany jedynie z drugim watkiem, czyli z tym watkiem gdzie sa generowane dane.

A to moje dotychczasowe wypociny:

unit der;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, TeEngine, Series, TeeProcs, Chart;

type
  TMainForm = class(TForm)
    btnStart: TButton;
    btnStop: TButton;
    Timer1: TTimer;
    Chart1: TChart;
    Series1: TBarSeries;
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private

  public
    check:boolean;
  end;

TTest = class(TThread)
  private
    FForm : TForm;
    FColor : TColor;
  protected
    procedure Execute; override;
  public
      bb:array[1..66] of real;
      jj_d:integer;
      check_t, timer_check:boolean;
      procedure Draw;
end;

var
  MainForm: TMainForm;
  Rectangle : TTest;

implementation

{$R *.DFM}

procedure TTest.Execute;
var
  i:integer;
begin
  FreeOnTerminate := True;
  while not (Application.Terminated) or (Terminated) do
    begin
       for i:=1 to 66 do
            begin
               bb[i]:=5+Random(10)/10;
            end;
     Draw;
     Synchronize(Draw);
   end;
end;

procedure TTest.Draw;
var
i:integer;
begin
  MainForm.Series1.Clear;
      with MainForm.Series1 do
          begin
              for i:=1 to 66 do Add(bb[i],IntToStr(i),clRed);
          end;
end;

procedure TMainForm.btnStartClick(Sender: TObject);
begin
  Timer1.Enabled:=True;
  if not Assigned(Rectangle) then Rectangle := TTest.Create(True)
    else Rectangle.Resume;
end;

procedure TMainForm.btnStopClick(Sender: TObject);
begin
  Timer1.Enabled:=False;
  Rectangle.Suspend; // wstrzymaj
  btnStart.Caption := 'Wznów';
end;

procedure TMainForm.Timer1Timer(Sender: TObject);
var
i:integer;
begin
  Sleep(100);
end;

initialization
Rectangle:= TTest.Create(True);
Randomize;
end.
0

Tak. Istnieje taka możliwość.

0

A mogłbym prosić o jakies wskazówki, bowiem nie wiem jak sie do tego zabrać.

Kochzg

0
Kochzg napisał(a)

Witam
Mam taki problem, że w pewnym wątku genereję tablicę danych bb[1..66] która chciałbym wyświetlić w postaci słupków w komponencie TChar. Do tej pory korzystałem z komponentu TChar który umieszcziłem na formie głownej. Jednak gdy dokonuje jakieś operacji w głównym wątku (zasymulowałem to w formie Sleep) to dane te są wyświetlane bardzo wolno. I tutaj moje pytanie, czy istnieje możliwość stworzenia komponentu TChar, który bedzie powiązany jedynie z drugim watkiem, czyli z tym watkiem gdzie sa generowane dane.

A to moje dotychczasowe wypociny:

unit der;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, TeEngine, Series, TeeProcs, Chart;

type
  TMainForm = class(TForm)
    btnStart: TButton;
    btnStop: TButton;
    Timer1: TTimer;
    Chart1: TChart;
    Series1: TBarSeries;
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private

  public
    check:boolean;
  end;

TTest = class(TThread)
  private
    FForm : TForm;
    FColor : TColor;
  protected
    procedure Execute; override;
  public
      bb:array[1..66] of real;
      jj_d:integer;
      check_t, timer_check:boolean;
      procedure Draw;
end;

var
  MainForm: TMainForm;
  Rectangle : TTest;

implementation

{$R *.DFM}

procedure TTest.Execute;
var
  i:integer;
begin
  FreeOnTerminate := True;
  while not (Application.Terminated) or (Terminated) do
    begin
       for i:=1 to 66 do
            begin
               bb[i]:=5+Random(10)/10;
            end;
     Draw;
     Synchronize(Draw);
   end;
end;

procedure TTest.Draw;
var
i:integer;
begin
  MainForm.Series1.Clear;
      with MainForm.Series1 do
          begin
              for i:=1 to 66 do Add(bb[i],IntToStr(i),clRed);
          end;
end;

procedure TMainForm.btnStartClick(Sender: TObject);
begin
  Timer1.Enabled:=True;
  if not Assigned(Rectangle) then Rectangle := TTest.Create(True)
    else Rectangle.Resume;
end;

procedure TMainForm.btnStopClick(Sender: TObject);
begin
  Timer1.Enabled:=False;
  Rectangle.Suspend; // wstrzymaj
  btnStart.Caption := 'Wznów';
end;

procedure TMainForm.Timer1Timer(Sender: TObject);
var
i:integer;
begin
  Sleep(100);
end;

initialization
Rectangle:= TTest.Create(True);
Randomize;
end.

Czemu masz w Execute 2 razy Draw ? Jak zapewne wiesz odwołania do wątku głównego powinno się robić przez synchronize. Zresztą sama operacja na komponencie jest w metodzie draw więc powinna działać szybko. Może wykorzystaj OnThreadTerminate (czy jakoś tak) i tam wywołaj Draw, z tego co pamiętam to zdarzenie wykonywane jest zawsze w kontekscie wątku głównego. Ewentualnie co mi przychodzi do głowy, to jakieś zablokowanie malowania na czas ładowania danych do komponentu (nie wiem jak to jest w wykresami, ale podejrzewam że coś takiego powinno być, ewentualnie tworzyć jakoś serię i dodać ją w całości)

0

Do odwołania sie dwukrotnie do procedury Draw jest moim błedem. Jednak odwołanie sie do głównego watku powoduje bardzo wolne wyswietlanie tych danych. Spowodowane jest to wstawieniem komendy Sleep do procedury Timer1Timer. Jednak zalezy mi na tym zeby dane te były wyswietlane szybko (w miare mozliwości komputera) niezaleznie do tego co robię w głównym wątku

Kochzg

0

Nikt mi nie chce pomóc :(((((
Chyba przyszły wakacje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1