Announcement

Collapse
No announcement yet.

TService : Dienst verursacht 99% Auslastung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • TService : Dienst verursacht 99% Auslastung

    Hallo,
    <p>
    mein Dienst verursacht eine 99%ige Auslastung im Task-Manager. Was kann ich tun ?<p>
    Auszug aus dem Quellcode :
    <p><p>
    While not Terminated Do<p>
    Begin<p>
    If not bPaused then<p>
    Begin<p>
    .<p>
    .<p>
    .<p>
    End;<p>
    <p>
    ServiceThread.ProcessRequests(false);<p>
    <p>
    End;<p>
    <p>

  • #2
    Hallo,

    die Frage ist: "<i>Welche Nutzfunktion arbeitet der Dienst in dieser Endlos-Schleife ab?</i>". Wenn es im Dienst nur darum geht, auf eine bestimmte Situation zu warten und erst dann kurzzeitig etwas zu machen, kann man folgendes machen:
    <pre>
    <b>var</b>
    dwResult : DWORD;
    <b>begin</b>
    FRequestSyncEvent := CreateEvent(<b>nil</b>, False, False, <b>nil</b>);
    FSyncDoneEvent := CreateEvent(<b>nil</b>, False, False, <b>nil</b>);
    <font color="#003399"><i>//</i></font>
    <b>while</b> (<b>not</b> Terminated) <b>do</b>
    <b>begin</b>
    dwResult := MsgWaitForMultipleObjects(1, FRequestSyncEvent, False,
    INFINITE, QS_ALLINPUT);
    <b>case</b> dwResult <b>of</b>
    WAIT_OBJECT_0 : <b>begin</b>
    <b>if</b> (<b>not</b> Terminated) <b>then</b>
    <b>if</b> Assigned(FSyncMethod) <b>then</b>
    <b>begin</b>
    ResetEvent(FRequestSyncEvent);
    <font color="#003399"><i>// Nutzfunktion aufrufen </i></font>
    FSyncMethod;
    <font color="#003399"><i>// ist fertig</i></font>
    SetEvent(FSyncDoneEvent);
    <b>end</b>;
    <b>end</b>;
    WAIT_OBJECT_0 + 1 : Application.ProcessMessages;
    <b>else</b>
    Application.ProcessMessages;
    <b>end</b>;
    <b>end</b>;
    <font color="#003399"><i>// aufraeumen</i></font>
    CloseHandle(FRequestSyncEvent);
    CloseHandle(FSyncDoneEvent);
    <b>end</b>;
    </pre>
    Innerhalb der Schleife legt sich der Dienst über die Win32-API-Funktion <b>MsgWaitForMultipleObjects</b> auf die Lauer, wobei er erst dann kurz anläuft, wenn das vereinbarte <b>Event</b> ausgelöst wird.

    Wenn dieser Aufwand zu groß erscheint, kann man in der Schleife auch eine <b>Sleep</b>-Anweisung unterbringen, um die "Herdplatte" CPU auf die kleinste Temperaturstufe zu schalten:
    <pre>
    ...
    // 100 Millisekunden warten, bevor die Schleife erneut durchlaufen wird
    Sleep(100);
    ...
    </pre&gt

    Comment


    • #3
      Hallo Herr Kosch,<p><p>

      vielen Dank für Ihre Reaktion, aber bei mir bleibt der Service bei "WaitForMultipleObjects" stehen. Muß ich das Ereignis "FRequestSyncEvent" selber auslösen, und wenn ja, wie

      Comment


      • #4
        Hallo Herr Kosch,<p><p>
        vielen Dank für Ihre Reaktion, aber bei mir bleibt der Service bei "WaitForMultipleObjects" stehen. Muß ich das Ereignis "FRequestSyncEvent" selber auslösen, und wenn ja, wie

        Comment


        • #5
          Hallo,

          das Programm löst in meinem Beispiel im primären Thread das Event über <b>SetEvent</b> aus:

          <pre>

          <b>procedure</b> TFrmInThread.SynchronizedCall(aMethod: TThreadMethod);
          <b>begin</b>
          FSyncMethod := aMethod;
          SetEvent(FRequestSyncEvent);
          WaitForSingleObject(FSyncDoneEvent, INFINITE);
          ResetEvent(FSyncDoneEvent);
          <b>end</b>;

          </pre>

          Der Sinn von <b>WaitForSingleObject</b> besteht ja gerade darin, als "Stopper" zu wirken, der die Anwendung solange anhält, bis die vereinbarte Situation erkannt wird. Zwischen SetEvent und WaitForSingleObject könnte der primäre Thread irgend etwas vernünftiges machen, als nur zu warten :-

          Comment


          • #6
            Vielen Dank!!

            Comment

            Working...
            X