So habe mich jetzt mal entgültig für Tryer Vorschlag entschieden.
Es scheint alles so zu funktionieren wie vorher.
Destotrotz muss ich nochmal nerven.
Ich verwende jetzt
Delphi-Quellcode:
if not VisDataThread.Suspended then
VisDataThread.Halt;
anstelle von
VisDataThread.Suspend;
Delphi-Quellcode:
procedure TVisDataThread.ResumeVis;
var
p1: PDWORD;
begin
WaitCounter := 0;
p1 := FShareMemPointer;
Inc(p1, 70);
p1^ := 0;
if Suspended then
Continue;
end;
Continue anstelle von Resume.
1 Frage ist "Halt" nicht etwas ungünstig von der namensgebung gewählt?
Eigentlich beendet der Befehlt Halt ja die ganze Anwendung .. (OK hier als Privat deklariert)
Es geht mir aber um die Namensgebung
Delphi-Quellcode:
procedure TVisDataThread.Execute;
const
_SECOND = 10000000;
var
qwDueTime: Int64;
liDueTime: _LARGE_INTEGER;
ErrMsg:
string;
begin
if VisTimer = 0
then
Exit;
// Create a negative 64-bit integer that will be used to
// signal the timer 1/4 seconds from now.
qwDueTime := -1 * (_SECOND
div 4);
// Copy the relative time into a LARGE_INTEGER.
liDueTime.LowPart := DWORD(qwDueTime
and $FFFFFFFF);
liDueTime.HighPart := longint(qwDueTime
shr 32);
if MySetWaitableTimer(VisTimer,
// handle to a timer object
TLargeInteger(liDueTime),
// when timer will become signaled
FDelayMS,
// periodic timer interval
nil,
// pointer to the completion routine
nil,
// data passed to the completion routine
False
{flag for resume state})
then
// Following sentences are repeated every FDelayMS interval all the time from initial
// start up to program end.
repeat
// We need to re-adjust timer interval according to the parameter "DelayMS" of vis plug-in.
// (in case we exchange vis plug-ins)
if FDelayMSChanged
then
begin
FDelayMSChanged := False;
CancelWaitableTimer(VisTimer);
MySetWaitableTimer(VisTimer, TLargeInteger(liDueTime), FDelayMS,
nil,
nil, False);
end;
if WaitForSingleObject(VisTimer, 1000
{1sec}) = WAIT_OBJECT_0
then
begin
DoOnVisTimer;
end else
Terminate;
SuspendIfHalted;
// Added
until Terminated
else
begin
ErrMsg := SysErrorMessage(GetLastError);
ShowErrorMsgBox(ErrMsg);
Terminate;
end;
end;
Wenn ich den Thread erstelle
Delphi-Quellcode:
constructor TVisDataThread.Create(var DataReadyMsg: HWND; var MemPointer: Pointer);
begin
inherited Create(True);
DriveThreadId := 0;
FShareMemPointer := GetBufferAddress;
MemPointer := FShareMemPointer;
VisTimer := CreateWaitableTimer(nil, False, 'BassVisTimer');
if VisTimer <> 0 then
begin
DataReadyMsg := FDataReadyMsg;
FDelayMS := 0;
ModuledelayMs := 0;
FDelayMSChanged := False;
FThreadReady := True;
end;
LockFlag := TCriticalSection.Create;
end;
erstelle ich eine CriticalSection
Die 2 Frage ist nun wo ist der Unterschied zwischen CriticalSection und EntercriticalSection?
Nicht das selbe?
Wo wäre es dann angebracht wenn nicht das gleiche
EntercriticalSection und LeaveCriticalSection in TVisDataThread.Execute unterzubringen?
Jetzt nicht schimpfen.. Ja ich muss mich mit dem Thema noch mehr beschäftigen
War ja bisher nicht nötig da in älteren vers. von Delphi das problem bisher nicht auftrat.
gruss