Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Thread doesn't like my data (ObjectList Or XML) 1

Status
Not open for further replies.

Opieo

Programmer
Jul 26, 2006
454
GB
Okay, so my program has a function being added that is going to be a slightly heavy procedure. However, I did not want to hold up the users with it since it will only need to run once and can go on in the background. So I decided I would push it into its own little thread. This has been one of the toughest things for me to get to work. So here I am again asking my fellow Delphi programmers for advice.
I do not have my code (well, it may still be in the history) for my ObjectList implementation of this. But the idea was that I was trying to run my thread and pass it an object list. For the life of me I could not turn my ObjectList back into the objects it was meant to be. It would seem to get the Count of objects right, but would not allow me to give them the structure from the Object I had defined.
My current attempt is with XML, but now it will not read XML properly. Since I was having some trouble I spun off this little section of code into its own small program for testing purposes, but I still run into problems.

Here is my Unit1 (sorry for the length):
Code:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, xmldom, XMLIntf, msxmldom, XMLDoc, StdCtrls, ExtCtrls,
  StrUtils, DB, ADODB, shellapi, Contnrs, ActiveX;

type
  TPriceHist = class(TObject)
   PartDesc : String[50];
   LessFin : String[13];
   DateEff : String[20];
   PPrice  : Double;
  end;
type TPriceList = array of TPriceHist;
type
  THistThread = class(TThread)
  protected
    procedure Execute; override;
  public
    ConnStr : widestring;
    Priority: TThreadPriority;
  end;

type
  TForm1 = class(TForm)
    XMLDocument1: TXMLDocument;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    function RunThread(): THistThread;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
implementation
{$R *.dfm}

procedure XML2Prices(var MyPrices : TPriceList; var PriceCount : Integer; var Progrm : String);
 var
  XMLDoc : IXMLDocument;
  iNode, pNode, cNode, dNode : IXMLNode;
  thisprog : string;
 begin
  XMLDoc := TXMLDocument.Create(nil);
  XMLDoc.LoadFromFile('myPrices.xml');
//  XMLDoc.FileName := 'myPrices.xml';
//  XMLDoc.Active := True;
  if XMLDoc.ChildNodes.First = nil then begin
   ShowMessage('nil');
   PriceCount := -1;
   Exit;
  end;
  iNode := XMLDoc.DocumentElement.ChildNodes.FindNode('program');
  thisprog := iNode.Attributes['text'];
  ShowMessage (thisprog);
  XMLDoc.Active := False;
 end;

function TForm1.RunThread(): THistThread;
 var
  MyHistThread : THistThread;
 begin
  MyHistThread := THistThread.Create(true);
  MyHistThread.FreeOnTerminate := true;
  MyHistThread.ConnStr := 'temp connection string yo';
  MyHistThread.Priority := tpNormal;
  MyHistThread.Resume;
  Result := MyHistThread;
 end;

procedure THistThread.Execute;
 var
  Qry : TADOQuery;
  i, PriceCount : integer;
  MyPrices : TPriceList;
  Progrm : String;

 begin
  Application.ProcessMessages;
  inherited;
  CoInitialize(nil); //CoInitialize was not called
  Qry := TADOQuery.Create(nil);
  try
   PriceCount := 0;
   Qry.ConnectionString := ConnStr;
   Qry.CursorLocation := clUseClient;
   Qry.LockType := ltReadOnly;
   Qry.CursorType := ctOpenForwardOnly;
   if FileExists('myPrices.xml') then
    XML2Prices(MyPrices, PriceCount, Progrm)
   else
    Exit;
   Application.ProcessMessages;
   //ShowMessage(IntToStr(PriceCount));
   for i := 0 to PriceCount - 1 do begin
    {ShowMessage (ThisPrice.LessFin);
    Qry.Open;
    while not Qry.Eof and not Terminated do begin
     Qry.Next;
    end; //while
    if Terminated then break;
    Qry.First; }
   end; // for
  finally
   Qry.Free;
  end;
  CoUninitialize();
 end;

procedure TForm1.Button1Click(Sender: TObject);
 begin
  RunThread();
 end;

procedure TForm1.Button2Click(Sender: TObject);
 begin
  Close;
 end;

end.

Every time I click on Button one, the message box that pops up is random height and length, and hit or miss whether or not it will list the program. Here is the XML (that my main program generated just fine and dandy, but also cannot read well).

Code:
<newPrices app="D:\Program Mastah\Program Master\ProgramMaster.exe">
?
<program text="GMT166">
?
<part text="Front Door LH">
<details text="15929259" Date="9/9/9981" Price="5.5867"/>
</part>
?
<part text="Front Door RH">
<details text="15929260" Date="9/9/9995" Price="5.5867"/>
</part>
?
<part text="Front Rocker Molding LH">
<details text="25868660" Date="9/9/9993" Price="10.9259"/>
</part>
?
<part text="Front Rocker Molding RH">
<details text="25868676" Date="9/9/9997" Price="10.9259"/>
</part>
?
<part text="Hood Molding">
<details text="25778383" Date="9/9/9993" Price="18.05"/>
</part>
?
<part text="Rear Door LH">
<details text="15929261" Date="9/9/9995" Price="4.9783"/>
</part>
?
<part text="Rear Door RH">
<details text="15929262" Date="9/9/9997" Price="4.9783"/>
</part>
?
<part text="Rear Rocker Molding LH">
<details text="25868659" Date="9/9/9999" Price="3.1511"/>
</part>
?
<part text="Rear Rocker Molding RH">
<details text="25868675" Date="9/9/9997" Price="3.1511"/>
</part>
?
<part text="Spoiler">
<details text="15929267" Date="9/9/9989" Price="63.0797"/>
</part>
</program>
</newPrices>

Again, sorry for the length. I probably should have linked to my docs somewhere, but I tend to be weary of links myself. It is worth noting that I have never had a problem generating the XML from my main form procedure. It was meant to dump the data into an XML and then go about its business after calling the thread. The thread just seems to hate me.

~
“Your request is not unlike your lower intestine: stinky, and loaded with danger.” — Ace Ventura.
 
While I still have nothing on the whole passing ObjectList to my thread, I think I am all set now using XML.

The problem seems to not really be that I was not accessing XML correctly, but that using ShowMessage as my error trapping from a thread is the problem. Just slapping a Label on the main form and having the thread set that to the text that was in the ShowMessage seems to turn up fine every time.

To prove my point I set thisprog := 'lar lar lar' and then the very next line was the ShowMessage. Same problem as using the XML.

In short, ShowMessage from a variable in a thread is bad. Problem solved (being that I had solved my problems before I even posted this thread).

However, at least this all drove me to learn a lot about XML from Delphi. Yay bright side.

~
“Your request is not unlike your lower intestine: stinky, and loaded with danger.” — Ace Ventura.
 
avoid using visual vcl components in your threads. something simple like setting the caption of a tlabel can produce inpredictable results (showmessage also belongs to this category)

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Will do, thanks for the heads up.

~
“Your request is not unlike your lower intestine: stinky, and loaded with danger.” — Ace Ventura.
 
Oooo. Thank you very much.

~
“Your request is not unlike your lower intestine: stinky, and loaded with danger.” — Ace Ventura.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top