Solved

Allowing two separate Delphi applications/processes to communicate

Posted on 2006-06-28
7
222 Views
Last Modified: 2010-05-18
Hello experts.

I have a very sorted large string list (up to 30,000 items) that I need to (a) read from disk and then (b) search and return an item from the list.  I am thinking of loading this to a TStringList.  However, the search and item return may have to be repeated many times in a given session, and so I would like to avoid repeating the bottleneck of reading the large list into memory each time a search is requested.

So is there a means to (1) Load the string list into memory one time at the beginning of a session, and (2) have a separate process search the string list (already loaded in memory) and return the item?  It sounds like a DLL to me, but I have never used DLLs and so would need help...or a better idea.

I am posting the question with higher points in the hopes of some basic code examples.

Thanks.

Roger
0
Comment
Question by:Roger_Hanggi
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
  • 2
  • +1
7 Comments
 

Expert Comment

by:AshusCZ
ID: 17001725
You might try to use threads. No need for separate applications.

Here's a simple example of how to use threads:

unit ThrWrite;

interface

uses
  Classes, ComCtrls, forms;

type
  TThrWrite = class(TThread)
  private
    FProgressBar : TProgressBar;
  protected
    procedure Execute; override;
  public
    constructor Create(var i:integer);
    property ProgressBar: TProgressBar write FProgressBar;
    procedure CCount;
  end;

var o: integer;

implementation

{ TThrWrite }

constructor TThrWrite.Create(var i:integer);
begin
inherited Create(true);
o:=i;
end;


procedure TThrWrite.Execute;
begin
Fuck;
end;


procedure TThrWrite.CCount;
begin
repeat
Inc(o);
FProgressBar.position:=o;
until o=50000;
end;

end.


/////////////////////////////////


unit ThrWrite;

interface

uses
  Classes, ComCtrls, forms;

type
  TThrWrite = class(TThread)
  private
    FProgressBar : TProgressBar;
  protected
    procedure Execute; override;
  public
    constructor Create(var i:integer);
    property ProgressBar: TProgressBar write FProgressBar;
    procedure CCount;
  end;

var o: integer;

implementation

{ TThrWrite }

constructor TThrWrite.Create(var i:integer);
begin
inherited Create(true);
o:=i;
end;


procedure TThrWrite.Execute;
begin
CCount;
end;


procedure TThrWrite.CCount;
begin
repeat
Inc(o);
FProgressBar.position:=o;
until o=50000;
end;

end.
0
 

Expert Comment

by:AshusCZ
ID: 17001742
oops..

procedure TThrWrite.Execute;
begin
Fuck;    ------->      CCount;
end;

sorry for that, it was given to me from some rude guy and i missed one occurence while replacing..
0
 
LVL 10

Assisted Solution

by:atul_parmar
atul_parmar earned 75 total points
ID: 17001777
Using a DLL for string handling will require you to deploy the BorlandMM along with your application. If that's not a problem then you can go with a DLL.

Another thing you can do is to load the list when your session starts and when you need to find the item, just use the previously loaded list.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 10

Expert Comment

by:atul_parmar
ID: 17001817
var
  MyStrings : TStringList;

function FindString(StringToFind : String) : Boolean;
var
  Idx : Integer;
begin
  If Not Assigned(MyStrings) then // load the list
  begin
    MyStrings := TStringList.Create;
    MyStrings.LoadFromFile('FileName');
    MyStrings.Sort;
  end;
  Result := MyStrings.Find(StringToFind, Idx);
end;
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 17004807
if the TStringlist is sorted, and you are searching for a complete string, then you can just do
i := SL.indexof('string'); which will be very fast and not require a thread
0
 
LVL 17

Accepted Solution

by:
TheRealLoki earned 175 total points
ID: 17005120
This is how I'd do what you want, by using a thread.
The thread is the only thing dealing with the list, so it loads it, and searches it when you ask it to.
It returns the 1st string it finds containing your search word

You will need a TButton, a TMemo, a Button1Click, and a FormClose event

unit unit1;

interface

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

type
    TOnStringListFoundWordEvent = procedure(Sender: TObject; const SearchString: string; FoundString: string; FoundIndex: integer) of object;
type
    TOnStringListNotFoundWordEvent = procedure(Sender: TObject; const SearchString: string) of object;

type TStringListLoadAndSearchThread = class(TThread)
    private
        SL: TStringList;
        foundindex: integer;
        foundcompletestring: string;
        OnStringListFoundWordEvent: TOnStringListFoundWordEvent;
        OnStringListNotFoundWordEvent: TOnStringListNotFoundWordEvent;
    public
        SearchString: string;
        constructor Create(Listfilename: string; OnFoundEvent_: TOnStringListFoundWordEvent; OnNotFoundEvent_: TOnStringListNotFoundWordEvent);
        procedure Execute; override;
// synchronized events
        procedure FoundString;
        procedure NotFoundString;
    end;

type
  TForm2 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    procedure OnStringListFoundWord(Sender: TObject; const SearchString: string; FoundString: string; FoundIndex: integer);
    procedure OnStringListNotFoundWord(Sender: TObject; const SearchString: string);
  public
    { Public declarations }
    workerthread: TStringListLoadAndSearchThread;
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

{ TStringListLoadAndSearch }

constructor TStringListLoadAndSearchThread.Create(Listfilename: string;
  OnFoundEvent_: TOnStringListFoundWordEvent;
  OnNotFoundEvent_: TOnStringListNotFoundWordEvent);
    begin
        inherited Create(true);
        OnStringListFoundWordEvent := OnFoundEvent_;
        OnStringListNotFoundWordEvent := OnNotFoundEvent_;
        SL := TStringList.Create;
        if FileExists(ListFilename) then
          SL.LoadFromFile(ListFIlename);
    end;

procedure TStringListLoadAndSearchThread.Execute;
    var
        i: integer;
    begin
        while (not terminated) and (SearchString <> '') do
        begin
            foundindex := -1;
            foundcompletestring := '';
            i := 0;
            while ( (not Terminated) and (foundindex = -1) and (i < SL.Count) ) do
            begin
                if pos(SearchString, SL[i]) > 0 then
                begin
                    foundindex := i;
                    foundcompletestring := SL[i];
                end
                else inc(i);
            end;
            if (not Terminated) and (foundindex <> -1) then
            begin
                synchronize(FoundString);
                Suspended := True;
            end
            else if (not Terminated) and (foundindex = -1) then
            begin
                synchronize(NotFoundString);
                Suspended := True;
            end;
        end;

    end;

procedure TStringListLoadAndSearchThread.FoundString;
    begin
        if assigned(OnStringListFoundWordEvent) then
          OnStringListFoundWordEvent(self, SearchString, FoundCompleteString, FoundIndex);
    end;

procedure TStringListLoadAndSearchThread.NotFoundString;
    begin
        if assigned(OnStringListNotFoundWordEvent) then
          OnStringListNotFoundWordEvent(self, SearchString);
    end;

procedure TForm2.Button1Click(Sender: TObject);
    begin
        if not assigned(workerthread) then
          workerthread := TStringListLoadAndSearchThread.Create('strings.txt', OnStringListFoundWord, OnStringListNotFoundWord);
        if workerthread.Suspended then
        begin
            workerthread.SearchString := edit1.Text;
            workerthread.Resume;
        end
        else
          showmessage('I am still searching another word');
    end;

procedure TForm2.OnStringListFoundWord(Sender: TObject; const SearchString: string; FoundString: string; FoundIndex: integer);
    begin
        Memo1.Lines.Add('Found "' + SearchString + '" in string "' + FoundString + '" at position ' + IntToStr(FoundIndex));
    end;

procedure TForm2.OnStringListNotFoundWord(Sender: TObject; const SearchString: string);
    begin
        Memo1.Lines.Add('Did not find "' + SearchString + '"');
    end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    if assigned(workerthread) then
    begin
        workerthread.terminate;
        if workerthread.suspended then workerthread.resume;
        workerthread.waitfor;
    end;
end;

end.

0
 

Author Comment

by:Roger_Hanggi
ID: 17008814
Thanks for your help.  I wanted to split points between Atul Parmar for clarifying the issues of using a DLL and TheRealLoki for a complete code example of using threads.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

691 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question