Solved

Allowing two separate Delphi applications/processes to communicate

Posted on 2006-06-28
7
200 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 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Activex loadlibrary and show parented form issue 6 286
Downloading email attachments 2 67
Working with hours 3 46
Need Help Delphi 2010 CheckBox1 Stored value in memo 13 57
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
Both in life and business – not all partnerships are created equal. As the demand for cloud services increases, so do the number of self-proclaimed cloud partners. Asking the right questions up front in the partnership, will enable both parties …

910 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now