Improve company productivity with a Business Account.Sign Up

x
?
Solved

Allowing two separate Delphi applications/processes to communicate

Posted on 2006-06-28
7
Medium Priority
?
238 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
  • 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 300 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
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
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 700 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

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This is an update to some code that someone else posted on Experts Exchange. It is an alternate approach, I think a little easier to use, & makes sure that things like the Task Bar will update.
Watch the video to know the simple way to remove or recover or reset lost or forgotten passwords of Outlook PST file. With Kernel Outlook Password Recovery tool such operation is very easy to perform. It is a freeware with limitation to use with 500…
To export Lotus Notes to Outlook PST or Exchange and Domino Server files to Exchange Server or PST files with ease, go for Kernel for Lotus Notes to Outlook conversion tool. Through the video, you can watch the conversion process. A common user with…

606 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