Re: [lazarus] TRunInThread - Progress, but new problem
On Sun, 5 Mar 2006, A.J. Venter wrote: On Sunday 05 March 2006 08:43, A.J. Venter wrote: Well since my last mail on this a few weeks ago, I have made quite a bit of progress in my attempts to create a component that will allow me to call a tprocess in a thread while retrieving the output live. The structure I have no compiles, and can be placed on a form - it is all but right. The only trouble is - when I call the run method, it throws an access violation, the stack trace places it at line 76 (the line where I call FProcessThread.resume), I did a check and the first line of the execute method does not ever get executed. Mmmm, I think I know now why this is happening, though now I have even LESS of an idea how to prevent it. I instantiated TProcessThread directly in a test program (obviously this left me with no events or such but I was just trying to see if it worked) when I call TProcessThread.Create the program dies with error 232 complaining that there isn't a thread driver. I checked the lpr, it calls cthreads. I checked lazarus.pp - that too calls cthreads, the only thing I can imagine is that I must somehow call cthreads in olpack, putting it in olpack.lpk doesn't work - lazarus recreates the file on compile/save apparently, putting it in runinthread.pas doesn't work (probably because it's not early enough in the uses clause) - leaving me unable to determine where I SHOULD add it - or is this the IDE telling me that what I am trying to do is simply not possible ? You should add it in the program file (.lpr) of your test program. As the _first_ unit (possibly after cmem, if you use that too). Michael. _ To unsubscribe: mail [EMAIL PROTECTED] with unsubscribe as the Subject archives at http://www.lazarus.freepascal.org/mailarchives
Re: [lazarus] TRunInThread - Progress, but new problem
I checked the lpr, it calls cthreads. I checked lazarus.pp - that too calls cthreads, the only thing I can imagine is that I must somehow call cthreads in olpack, putting it in olpack.lpk doesn't work - lazarus recreates the file on compile/save apparently, putting it in runinthread.pas doesn't work (probably because it's not early enough in the uses clause) - leaving me unable to determine where I SHOULD add it - or is this the IDE telling me that what I am trying to do is simply not possible ? You should add it in the program file (.lpr) of your test program. As the _first_ unit (possibly after cmem, if you use that too). It IS the first unit in the lpr :( Could it be that it somehow just doesn't get compiled intoto the component ? Has anybody ever DONE a threaded component ? A.J. -- there's nothing as inspirational for a hacker as a cat obscuring a bug by sitting in front of the monitor - Boudewijn Rempt A.J. Venter Chief Software Architect OpenLab International www.getopenlab.com www.silentcoder.co.za +27 82 726 5103 _ To unsubscribe: mail [EMAIL PROTECTED] with unsubscribe as the Subject archives at http://www.lazarus.freepascal.org/mailarchives
[lazarus] TRunInThread - Progress, but new problem
Well since my last mail on this a few weeks ago, I have made quite a bit of progress in my attempts to create a component that will allow me to call a tprocess in a thread while retrieving the output live. The structure I have no compiles, and can be placed on a form - it is all but right. The only trouble is - when I call the run method, it throws an access violation, the stack trace places it at line 76 (the line where I call FProcessThread.resume), I did a check and the first line of the execute method does not ever get executed. At this stage the whole thing consists of two units. processthread.pas implements the TprocessThread class which is just a simple TThread descendent which runs a command. TRunInThread is a TComponent descendent which encapsulates TProcessThread with a component, setting up an instantiation of it, executing it, storing and updating the output etc. In theory it should all work so I really do not know why it's throwing a trace, perhaps somebody else can tell me what to change ? I attach both the units for your viewing pleasure. -- there's nothing as inspirational for a hacker as a cat obscuring a bug by sitting in front of the monitor - Boudewijn Rempt A.J. Venter Chief Software Architect OpenLab International www.getopenlab.com www.silentcoder.co.za +27 82 726 5103 unit processthread; {$mode objfpc}{$H+} interface uses Classes, SysUtils,process; Type TProcessThread = class(tthread) protected procedure Execute; override; public fcommand : String; Constructor Create(isSuspended : boolean); end; Var MemStream :TMemoryStream; Running:Boolean; implementation constructor TProcessThread.Create(isSuspended : boolean); begin MemStream := TMemoryStream.Create; inherited Create(isSuspended); end; procedure TProcessThread.Execute; const READ_BYTES = 2048; Var Process :Tprocess; n: LongInt; BytesRead: LongInt; begin Process := TProcess.create(nil);; Process.CommandLine := Fcommand; Running := True; {Actually run the thing and catch the output} BytesRead := 0; Process.Options := [poUsePipes,poNoConsole]; Process.Execute; while Process.Running do begin // make sure we have room MemStream.SetSize(BytesRead + READ_BYTES); // try reading it n := Process.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES); if n 0 then begin Inc(BytesRead, n); end else begin // no data, wait 100 ms Sleep(100); end; end; // read last part repeat // make sure we have room MemStream.SetSize(BytesRead + READ_BYTES); // try reading it n := Process.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES); if n 0 then begin Inc(BytesRead, n); end; until n = 0; MemStream.SetSize(BytesRead); Process.Free; Running := False; end; end. unit RunInThread; {$mode objfpc}{$H+} interface uses LResources,Classes, SysUtils,ProcessThread; Type TNewOutPutEvent = procedure(Sender: TObject;NewOutPut:TStringList) of object; TRunInThread = Class(TComponent) private FOutPut : TStringList; FNewOutPut :TStringlist; FProcessThread : TProcessThread; FCommand : String; FRunning : Boolean; FOnNewOuput : TNewOutPutEvent; FOnDone : TNotifyEvent; FLastSize : Integer; FLastMSize : Integer; procedure GetOutPut; destructor destroy; override; public constructor Create(AOwner: TComponent); procedure run; published property Command : String read FCommand write Fcommand; property OutPut: TStringLIst read FOutput; property Running: Boolean read FRunning; property OnNewOutput : TNewOutPutEvent read FOnNewOuput write FOnNewOuput; property OnDone : TNotifyEvent read FOnDone Write FOnDone; end; procedure Register; implementation procedure Register; begin RegisterComponents('OLPack',[TRunInThread]); end; Constructor TRunInThread.Create(AOwner: TComponent); Begin FLastSize := 0; FLastMSize := 0; FOutPut := TStringList.Create; FNewOutPut := TStringList.Create; FProcessThread := TProcessThread.Create(false); FProcessThread.FCommand := FCommand; if Assigned(FProcessThread.FatalException) then raise FProcessThread.FatalException; inherited create(AOwner); end; Destructor TRunInThread.Destroy; Begin FProcessThread.Suspend; FOutPut.Free; FNewOutPut.Free; FProcessThread.Terminate; inherited destroy; end; Procedure TRunInThread.GetOutPut; Begin FOutPut.LoadFromStream(MemStream); end; procedure TRunInThread.Run; Var I : Integer; Begin FProcessThread.Resume; FRunning := True; While Running do Begin If MemStream.Size FLastMSize then begin FLastMSize := MemStream.Size; GetOutPut; If
Re: [lazarus] TRunInThread - Progress, but new problem
On Sunday 05 March 2006 08:43, A.J. Venter wrote: Well since my last mail on this a few weeks ago, I have made quite a bit of progress in my attempts to create a component that will allow me to call a tprocess in a thread while retrieving the output live. The structure I have no compiles, and can be placed on a form - it is all but right. The only trouble is - when I call the run method, it throws an access violation, the stack trace places it at line 76 (the line where I call FProcessThread.resume), I did a check and the first line of the execute method does not ever get executed. Mmmm, I think I know now why this is happening, though now I have even LESS of an idea how to prevent it. I instantiated TProcessThread directly in a test program (obviously this left me with no events or such but I was just trying to see if it worked) when I call TProcessThread.Create the program dies with error 232 complaining that there isn't a thread driver. I checked the lpr, it calls cthreads. I checked lazarus.pp - that too calls cthreads, the only thing I can imagine is that I must somehow call cthreads in olpack, putting it in olpack.lpk doesn't work - lazarus recreates the file on compile/save apparently, putting it in runinthread.pas doesn't work (probably because it's not early enough in the uses clause) - leaving me unable to determine where I SHOULD add it - or is this the IDE telling me that what I am trying to do is simply not possible ? TIA A.J. -- there's nothing as inspirational for a hacker as a cat obscuring a bug by sitting in front of the monitor - Boudewijn Rempt A.J. Venter Chief Software Architect OpenLab International www.getopenlab.com www.silentcoder.co.za +27 82 726 5103 _ To unsubscribe: mail [EMAIL PROTECTED] with unsubscribe as the Subject archives at http://www.lazarus.freepascal.org/mailarchives