Board index » delphi » Access Violation using threads

Access Violation using threads

Hi All,

I have a problem that is causing me to tear out the remaining hairs on
my head.  I am using the TcpServer and TcpClient controls from the
Internet tab in D6 Ent to create a Peer-to-Peer Alert System.  In the
chat demo that comes with D6, they create a thread to update a memo
field with the recieved lines of text that come in.

I tried it without spawning the extra DataThread to update the
memRecv.Lines control, but nothing will update unless the extra
threading is used.  TcpServer is using threads as well.  The problem
comes when I shut the program down.  Everything works great while the
programs are running, alerts come in fine, all is well, but when I
attempt to shut the program down, I get:

The instruction at "0x77f83941" referenced memory at "0x00000010". The
memory could not be "written".

I don't receive this error when the program is closed after being run
from the IDE, only when the exe is run alone.  The error message does
not happen when I use nonblocking mode and no extra threading, but
then I cannot have more than one connection happening at once.  Any
idea's? I am being contracted to do this, and did not anticipate this
sort of block.  It does not affect the performance of the system, but
certainly, I cannot deliver a system that give access violations when
shut down.

Thanks,

Wes

remove the wontbesentjunkmail
to email me

 

Re:Access Violation using threads


Quote
> my head.  I am using the TcpServer and TcpClient controls from the
> Internet tab in D6 Ent to create a Peer-to-Peer Alert System.  In the

Is there a reason you're not using the Indy Components for this?

--
Jason Southwell
President & CEO
Arcana Technologies

Re:Access Violation using threads


Way to go not answering the question at all.

Wes,

Generally, when an error occurs outside the IDE and not inside, there is
usually a pointer or object that is being misused, or destroyed.

My advise would be to start using Try..Excepts to find exactly where the
problem occurs at, then analyzing what could be happening to that variable.

-Luke

Quote
"Jason Southwell" <ja...@southwell.net> wrote in message

news:3D29F350.8090306@southwell.net...
Quote
> > my head.  I am using the TcpServer and TcpClient controls from the
> > Internet tab in D6 Ent to create a Peer-to-Peer Alert System.  In the

> Is there a reason you're not using the Indy Components for this?

> --
> Jason Southwell
> President & CEO
> Arcana Technologies

Re:Access Violation using threads


Thank Luke, I will give that a try. The only problem I have is that
the error is happening after the forms onClose even completes. So I am
not sure.  If I stop using threads, all is well, but I can only accept
one connection concurrently.  That is bad :-(  I will try what you
have suggested, and see if I can come up with anything.

I have included the key events in my prog, could someone just have a
quick scan and confirm that everything is OK in it.

Thanks

Wes

** Not in any specific order **

here is my OnAccept Event of TcpServer:

procedure TForm2.TcpServerAccept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var
  txt: string;
  PopupAlertThread: TPopupAlertThread;
begin
  // Read the first line from the incoming
  txt:= ClientSocket.Receiveln();
  // create alert popup thread
  PopupAlertThread := TPopupAlertThread.Create(true);

  If txt = 'BUY' then
  begin
    PopupAlertThread.AlertType := 'BUY';
    PopupAlertThread.AlertData := ClientSocket.Receiveln();
    txt:= ClientSocket.Receiveln();
    While txt <> '' do
    begin
      PopupAlertThread.AlertMessage.Append(s);
      txt := ClientSocket.Receiveln();
    end;
  end;
  // Call Resume which will execute and synch/perform the popup
  PopupAlertThread.Resume;
end;

Here is the thread declaration

  // Thread for Alert Popup
  TClientDataThread = class(TThread)
  private
  public
    AlertType, AlertData : String;
    AlertMessage : TStrings;
    procedure threadPopupAlertMessage;
    constructor Create(CreateSuspended: Boolean);
    procedure Execute; override;
    procedure Terminate;
  end;

Here is the thread implementation

//------------- BEGIN My Popup Thread -------------------------------
constructor TPopupAlertThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := true;
  AlertMessage := TStringList.Create;
end;

procedure TPopupAlertThread.Terminate;
begin
  AlertMessage.Free;
  inherited;
end;

procedure TPopupAlertThread.Execute;
begin
  Synchronize(threadPopupAlertMessage);
  Self.FreeOnTerminate := True;
  Self.Free;
  If not Self.Terminated then Self.Terminate;
end;

procedure TPopupAlertThread.threadPopupAlertMessage;
begin
  Form2.ShowAlert(AlertType, AlertData, AlertMessage);
end;
//------------- END My Popup Thread ---------------------------

On Mon, 8 Jul 2002 17:36:33 -0700, "Luke Croteau [TriadNet Studios]"

Quote
<lu...@triadnet.net> wrote:
>Way to go not answering the question at all.

>Wes,

>Generally, when an error occurs outside the IDE and not inside, there is
>usually a pointer or object that is being misused, or destroyed.

>My advise would be to start using Try..Excepts to find exactly where the
>problem occurs at, then analyzing what could be happening to that variable.

>-Luke

>"Jason Southwell" <ja...@southwell.net> wrote in message
>news:3D29F350.8090306@southwell.net...
>> > my head.  I am using the TcpServer and TcpClient controls from the
>> > Internet tab in D6 Ent to create a Peer-to-Peer Alert System.  In the

>> Is there a reason you're not using the Indy Components for this?

>> --
>> Jason Southwell
>> President & CEO
>> Arcana Technologies

Re:Access Violation using threads


In general I love the Indy components, but I ended up at the TcpServer
components because they are functionally more simple.  The Indy are
bigger and have many functions that I don't need.  I am just sending
transactional messages (i.e. Connect, WriteLn, Disconnect).
BTW...Indy demo using threads had the same error.

On Mon, 08 Jul 2002 13:17:20 -0700, Jason Southwell

Quote
<ja...@southwell.net> wrote:
>> my head.  I am using the TcpServer and TcpClient controls from the
>> Internet tab in D6 Ent to create a Peer-to-Peer Alert System.  In the

>Is there a reason you're not using the Indy Components for this?

Re:Access Violation using threads


Wes,

I am very surprised that your code is working, besides all the real
processing that is done by your thread
is "synchronized" which makes me wonder why you are using threads in the
first place.

About the access violation:  try removing Self.Free in the thread's Execute
method.

Thinking about  "Self.Free",  isn't that  a very strange statement anyway ?

<Maarten>

Quote
"Wes Snider" <weswontbesentjunkm...@gmrn.org> wrote in message

news:j6mkiuoikubps9cmlbpj66tljjdvtp8o14@4ax.com...
Quote
> Thank Luke, I will give that a try. The only problem I have is that
> the error is happening after the forms onClose even completes. So I am
> not sure.  If I stop using threads, all is well, but I can only accept
> one connection concurrently.  That is bad :-(  I will try what you
> have suggested, and see if I can come up with anything.

> I have included the key events in my prog, could someone just have a
> quick scan and confirm that everything is OK in it.

> Thanks

> Wes

> ** Not in any specific order **

> here is my OnAccept Event of TcpServer:

> procedure TForm2.TcpServerAccept(Sender: TObject;
>   ClientSocket: TCustomIpClient);
> var
>   txt: string;
>   PopupAlertThread: TPopupAlertThread;
> begin
>   // Read the first line from the incoming
>   txt:= ClientSocket.Receiveln();
>   // create alert popup thread
>   PopupAlertThread := TPopupAlertThread.Create(true);

>   If txt = 'BUY' then
>   begin
>     PopupAlertThread.AlertType := 'BUY';
>     PopupAlertThread.AlertData := ClientSocket.Receiveln();
>     txt:= ClientSocket.Receiveln();
>     While txt <> '' do
>     begin
>       PopupAlertThread.AlertMessage.Append(s);
>       txt := ClientSocket.Receiveln();
>     end;
>   end;
>   // Call Resume which will execute and synch/perform the popup
>   PopupAlertThread.Resume;
> end;

> Here is the thread declaration

>   // Thread for Alert Popup
>   TClientDataThread = class(TThread)
>   private
>   public
>     AlertType, AlertData : String;
>     AlertMessage : TStrings;
>     procedure threadPopupAlertMessage;
>     constructor Create(CreateSuspended: Boolean);
>     procedure Execute; override;
>     procedure Terminate;
>   end;

> Here is the thread implementation

> //------------- BEGIN My Popup Thread -------------------------------
> constructor TPopupAlertThread.Create(CreateSuspended: Boolean);
> begin
>   inherited Create(CreateSuspended);
>   FreeOnTerminate := true;
>   AlertMessage := TStringList.Create;
> end;

> procedure TPopupAlertThread.Terminate;
> begin
>   AlertMessage.Free;
>   inherited;
> end;

> procedure TPopupAlertThread.Execute;
> begin
>   Synchronize(threadPopupAlertMessage);
>   Self.FreeOnTerminate := True;
>   Self.Free;
>   If not Self.Terminated then Self.Terminate;
> end;

> procedure TPopupAlertThread.threadPopupAlertMessage;
> begin
>   Form2.ShowAlert(AlertType, AlertData, AlertMessage);
> end;
> //------------- END My Popup Thread ---------------------------

> On Mon, 8 Jul 2002 17:36:33 -0700, "Luke Croteau [TriadNet Studios]"
> <lu...@triadnet.net> wrote:

> >Way to go not answering the question at all.

> >Wes,

> >Generally, when an error occurs outside the IDE and not inside, there is
> >usually a pointer or object that is being misused, or destroyed.

> >My advise would be to start using Try..Excepts to find exactly where the
> >problem occurs at, then analyzing what could be happening to that
variable.

> >-Luke

> >"Jason Southwell" <ja...@southwell.net> wrote in message
> >news:3D29F350.8090306@southwell.net...
> >> > my head.  I am using the TcpServer and TcpClient controls from the
> >> > Internet tab in D6 Ent to create a Peer-to-Peer Alert System.  In the

> >> Is there a reason you're not using the Indy Components for this?

> >> --
> >> Jason Southwell
> >> President & CEO
> >> Arcana Technologies

Re:Access Violation using threads


Ah yeah..  I didn't even notice that..

Quote
> > procedure TPopupAlertThread.Execute;
> > begin
> >   Synchronize(threadPopupAlertMessage);
> >   Self.FreeOnTerminate := True;
> >   Self.Free;
> >   If not Self.Terminated then Self.Terminate;
> > end;

Just remove the line with Self.Free from there and that'll work wonders..
heh..

Good call Maarten

Quote
"Maarten Bosteels" <no-...@nowhere.come> wrote in message

news:3d2cac52_1@dnews...
Quote
> Wes,

> I am very surprised that your code is working, besides all the real
> processing that is done by your thread
> is "synchronized" which makes me wonder why you are using threads in the
> first place.

> About the access violation:  try removing Self.Free in the thread's
Execute
> method.

> Thinking about  "Self.Free",  isn't that  a very strange statement anyway
?

> <Maarten>

> > procedure TPopupAlertThread.Execute;
> > begin
> >   Synchronize(threadPopupAlertMessage);
> >   Self.FreeOnTerminate := True;
> >   Self.Free;
> >   If not Self.Terminated then Self.Terminate;
> > end;

Re:Access Violation using threads


Quote
> Way to go not answering the question at all.

It was a simple question...  not intended to answer anything.

But thanks for being snippy about it anyway.

--
Jason Southwell
President & CEO
Arcana Technologies

Re:Access Violation using threads


Wes Snider <weswontbesentjunkm...@gmrn.org> wrote in
news:l0lkiusi4n5mda8ommvef592kmaqgde91r@4ax.com:

Quote
> BTW...Indy demo using threads had the same error.

Its something wrong with your threading technique then.

Are you accessing the UI?

--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
      "Programming is an art form that fights back"

   Want to keep up to date with Indy?

   Join Indy News - it free!

      http://www.atozedsoftware.com/indy/news/

ELKNews - Empower your News Reader! http://www.atozedsoftware.com

Other Threads