AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Merkwürdiges Verhalten von Named Pipes unter Win7
Thema durchsuchen
Ansicht
Themen-Optionen

Merkwürdiges Verhalten von Named Pipes unter Win7

Ein Thema von Dalai · begonnen am 29. Okt 2014 · letzter Beitrag vom 13. Nov 2014
 
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#1

Merkwürdiges Verhalten von Named Pipes unter Win7

  Alt 29. Okt 2014, 15:59
Hallo in die Runde ,

ich muss die Gemeinde mal wieder mit einem Problem belästigen, das ich selbst weder verstehe noch ohne Hilfe weiter untersuchen kann.

Kurz zur Vorgeschichte: Ich stieß kürzlich auf ein sehr merkwürdiges Verhalten einer meiner Applikationen unter Win7 mit IE10 und IE11 (mit IE8 oder IE9 trat das nicht auf), das irgendwie so aussah, als ob die benutzte Named Pipe blockiert ist. Also hab ich das genauer untersucht und eine Testapplikation geschrieben und das Problem dort in ähnlicher Art nachstellen können.

Was ist das Problem?
Jedes Senden eines Strings durch den Client erhöht die Anzahl der Instanzen auf der Pipe, wie man mit Sysinternals PipeList nachvollziehen kann, obwohl der Client direkt nach dem Senden des Strings und Flushen der Buffer die Verbindung mit Disconnect wieder trennt. Soweit sieht das erstmal nach keinem Problem aus, nur ist es so, dass sich der Pipe-Server in einer solchen Situation nicht mehr schließen lässt, weil dieser unendlich wartet, bis die Clients weg sind, obwohl das schon längst der Fall ist (Client-Prozess wurde beendet).

Lustigerweise tritt es mit der Testapplikation auch mit IE8 auf. Und es wird noch kurioser: es kommt nur zum Problem, wenn der Pipe-Server ein Manifest benutzt, das einerseits Laufzeit-Themes aktiviert und andererseits Kompatibilität mit Win7 beinhaltet; sobald eine der beiden Bedingungen nicht mehr zutrifft, ist das Problem verschwunden. Unter XP lässt sich das Problem gar nicht nachvollziehen; andere Windows-Versionen hab ich mit den Testprogrammen nicht getestet.

Aber kommen wir zum Wesentlichen: Ich benutze die Pipes-Komponente von Russell Libby, die man z.B. von dieser Seite bekommt. Als Beispielprogramme sollen diese beiden dienen:

Server:
Delphi-Quellcode:
unit Main;

interface

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

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    PipeServer1: TPipeServer;
    Button1: TButton;
    Edit1: TEdit;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure PipeServer1PipeMessage(Sender: TObject; Pipe: Cardinal;
      Stream: TStream);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}
{$R XP.res}

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    PipeServer1.Active:= False;
end;

procedure TForm1.PipeServer1PipeMessage(Sender: TObject; Pipe: Cardinal;
  Stream: TStream);
var text: string;
    dummy: integer;
    buffer: array of char;
begin
    SetLength(buffer, Stream.Size);
    dummy:= Stream.Read(buffer[0], Stream.Size);
    text:= String(PChar(buffer));
    SetLength(buffer, 0);
    Memo1.Lines.Add(text);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    Memo1.Lines.Add(IntToStr(PipeServer1.ClientCount) + ' clients connected');
    PipeServer1.Active:= False;
    PipeServer1.PipeName:= Edit1.Text;
    PipeServer1.Active:= True;
end;

end.
Client:
Delphi-Quellcode:
unit Main;

interface

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

type
  TForm1 = class(TForm)
    PipeClient1: TPipeClient;
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var myString: string;
    iLength: integer;
begin
    if PipeClient1.Connect(5000) then
    begin
        myString:= Edit1.Text;
        iLength:=Length(myString);
        // Send pipe message
        if PipeClient1.Write(mystring[1], iLength) then
        begin
            // Flush the pipe buffers
            PipeClient1.FlushPipeBuffers;
        end;
        PipeClient1.Disconnect;
    end;
end;

end.
Kann das Problem jemand nachvollziehen? Hatte das jemand bereits? Wie kann ich weiter vorgehen?

MfG Dalai
  Mit Zitat antworten Zitat
 


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