Autor Beitrag
TheNeon
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 408

Windows
VS2010 C#
BeitragVerfasst: Do 15.05.03 00:16 
hallo zusammen,

ich möchte eine Prozedur in einem eigenen Thread laufen lassen, doch so klappt es nicht. ............und zwar kriege ich folgenden Fehler:
Zitat:
Types of actual and formal var parameters must be identical

allerdings muss id doch ein Integer sein, oder nicht ?! ... so steht es wenigstens überall.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.Button1Click(Sender: TObject);
var id:Integer;

function txt(p:Pointer):Integer;
begin
  Label1.caption:='HALLO';
end;

begin
  CreateThread(nil,0, addr(txt), nil, 0, id);
end;

sorry, hab mit Threads noch nie gearbeitet ..... bzw. hat auch noch nicht geklappt egal wie ich es gemacht habe

DANKE

Moderiert von user profile iconTino: "wichtig" aus dem Titel entfernt.
Moderiert von user profile iconTino: Delphi- & Quote-Tags hinzugefügt.


Zuletzt bearbeitet von TheNeon am Do 15.05.03 09:05, insgesamt 1-mal bearbeitet
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 15.05.03 06:48 
Titel: Antwort *unwichtig*
Warum nimmst du nicht die TThread-Vorlage von Delphi? Dann kuckst du dir im Demo-Ordner das Threading-Demo an und dann sollte das klappen.

Aber hier mal eine kleine Demo, wenn du kein TThread-Objekt benutzen willst:
ausblenden volle Höhe 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:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ListBox1: TListBox;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }

  public
    { Public-Deklarationen }
  end;

var
  Form1             : TForm1;
  bRunning          : Boolean = FALSE;
  hThread           : Cardinal;
  //cs: TCriticalSection;
  cs                : RTL_CRITICAL_SECTION;

implementation

{$R *.dfm}

function FillLBThread(p: Pointer): Integer;
var
  i                 : Integer;
begin
  result := 0;
  i := 0;
  while bRunning = TRUE do
  begin
    EnterCriticalSection(cs);
    try
      Form1.Listbox1.Items.Add((IntToStr(i)));
      Form1.Label1.Caption := IntToStr(i);
    finally
      LeaveCriticalSection(cs);
    end;
    Inc(i);
    if i = 1000000 then
      EndThread(0);
    sleep(50);
  end;
  EndThread(0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ThreadID          : LongWord;
begin
  ThreadID := 1;
  hThread := BeginThread(nil, 0, @FillLBThread, nil, 0, ThreadID);
  if hThread <> 0 then
    bRunning := TRUE;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  bRunning := FALSE;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if bRunning = TRUE then
  begin
    bRunning := FALSE;
    TerminateThread(hThread, 0);
  end;
end;

initialization
  //cs := TCriticalSection.Create;
  InitializeCriticalSection(cs);

finalization
  //cs.Free;
  DeleteCriticalSection(cs);

end.

OK, das ist jetzt die dritte und wahrscheinlich letzte, da korrekte Version mit den CriticalSections. Im Code sind zwei Varianten: einmal die auskommentierte VCL Version mit der Unit SyncObjs, welche über 100 KB zur Exe beisteuert und einmal die verwendete reine Win32API-Version.
Die CriticalSections sind nötig, da im Thread auf globale Variablen bzw. Objekte zugegriffen wird und es gefährlich ist, wenn mehrer Threads gleichzeitig darauf zugreifen. CriticalSections sind dann wichtig, wenn mehrere Threads lesend und schreibend auf eine Variable zu greifen, um die Konsistenz zu gewährleisten.

Achtung der direkte API-Aufruf CreateThread sollte vermieden werden. Aus der Delphi-Hilfe:
Zitat:

BeginThread encapsulates the Win32 CreateThread API call, but unlike CreateThread, it sets the global IsMultiThread variable, thereby making the heap thread-safe.
TheNeon Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 408

Windows
VS2010 C#
BeitragVerfasst: Do 15.05.03 09:03 
danke, Luckie,

habe vorher mal sowas in der Art versucht, schlug fehl. Nun habe ich mir ein Beispiel aus einem Buch rausgenommen, doch das klappt dann nicht, da man 1-2 Abstürze bekommt. Dein Code klappt hervorragend.
:dance:

DANKE 8) :)