Unique copy of DLL

T

tony obrien

Hi,

I have written a Class Library in VB.net which provides Props/Meths to a
caller to hide the uglinesses of a TCP message protocol between a Client
and a Server.

All this works just fine.

Now I am trying to develop a LOAD TESTER app which spawns lotso' threads
each with this capability to bang the server.

The problerm is that the DLL class which worked just fine in a single
instance runs into problems because each version of the client-threads
seems to be reaching into the SAME copy of the DLL.

Everything I've read tells me to wrap the DLL areas that deal with
variables in SyncLocks... but this is NOT what I want... The DLL is NOT
STATELESS and so each new thread needs to have ITS OWN UNIQUE COPY of the
dll and its variables.

So the question is How Do I instantiate the DLL (class) in the thread to
ensure that it gets a NEW UNIQUE COPY running?

BTW, currently NONE of the Class's variables are public (though the
Props/Meths must be.) And the class DOES attempt to create a new copy
using...

Dim myDLLCls as theDLLClass
myDLLCls = New theDLLClass


but this does NOT generate a NEW copy in this thread.

Help !

regards,
tob
 
D

David Browne

tony obrien said:
Hi,

I have written a Class Library in VB.net which provides Props/Meths to a
caller to hide the uglinesses of a TCP message protocol between a Client
and a Server.

All this works just fine.

Now I am trying to develop a LOAD TESTER app which spawns lotso' threads
each with this capability to bang the server.

The problerm is that the DLL class which worked just fine in a single
instance runs into problems because each version of the client-threads
seems to be reaching into the SAME copy of the DLL.

Everything I've read tells me to wrap the DLL areas that deal with
variables in SyncLocks... but this is NOT what I want... The DLL is NOT
STATELESS and so each new thread needs to have ITS OWN UNIQUE COPY of the
dll and its variables.
. . .

That's just a design problem. If each client needs its own data, don't put
that data in shared scope. Create a class for each client to own, and place
that client's state data in the instance state of that class.

David
 
T

tony obrien

That's just a design problem. If each client needs its own data,
don't put that data in shared scope. Create a class for each client
to own, and place that client's state data in the instance state of
that class.

David

Thanks, David...

I do not disagree BUT what seems counter intuitive is that if I were to
take the SOURCE of the DLL and include it (as a class) to the project and
let each new thread create its copy of that class it, each thread WOULD
have its own, unique copy of the data and variables... but if I create
the class separately as a DLL I CAN NOT get a unique copy??

It seems you are suggesting that Multithreaded DLLs are ALWAYS shared and
can not operate a state machines. Seems like a HUGE whole a development
capability.

tob
 
D

David Browne

tony obrien said:
Thanks, David...

I do not disagree BUT what seems counter intuitive is that if I were to
take the SOURCE of the DLL and include it (as a class) to the project and
let each new thread create its copy of that class it, each thread WOULD
have its own, unique copy of the data and variables... but if I create
the class separately as a DLL I CAN NOT get a unique copy??

Yes you can. There are nested scopes in which you can declare state. You
are talking about the outermost scope: class scope. Each class you define
has a class scope (aka global, shared, static). Variables declared in this
scope, or reachable from a variable in this scope are shared among all
callers in the App Domain.

Variables declared or reachable from instance variables of a type created
separately for each client won't be shared.
It seems you are suggesting that Multithreaded DLLs are ALWAYS shared and
can not operate a state machines. Seems like a HUGE whole a development
capability.

No not at all. You can have any mix of sharing and separation of state you
want.

David
 
J

Jon Skeet [C# MVP]

tony obrien said:
I have written a Class Library in VB.net which provides Props/Meths to a
caller to hide the uglinesses of a TCP message protocol between a Client
and a Server.

All this works just fine.

Now I am trying to develop a LOAD TESTER app which spawns lotso' threads
each with this capability to bang the server.

The problerm is that the DLL class which worked just fine in a single
instance runs into problems because each version of the client-threads
seems to be reaching into the SAME copy of the DLL.

Firstly, you need to differentiate between "DLL" and "class". They're
not the same thing at all, and you seem to be treating them
interchangably.

It's fine to have one DLL, but it sounds like you probably want each
thread to have its own instance of your class. So long as none of your
variables are Shared, you should then be okay.

If that doesn't help, could you post a short but complete program which
demonstrates the problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
T

tony obrien

Firstly, you need to differentiate between "DLL" and "class". They're
not the same thing at all, and you seem to be treating them
interchangably.

It's fine to have one DLL, but it sounds like you probably want each
thread to have its own instance of your class. So long as none of your
variables are Shared, you should then be okay.

If that doesn't help, could you post a short but complete program
which demonstrates the problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

Thanks...

In this particular case I use them interchangeably since I created a DLL
from a single Class with nothing but private variables and public
Properties and Methods.... in my mind the Class is the DLL is the Class.

sorry for the confusion.

Recently I tried bringing that class (that created the DLL) into my test
program and it still does not operate after a 2nd or 3rd thread is begun...
so perhaps I have some deeper issues going on than I thought.

I am trying to get to the smallest thing that I know has the problem.
 
J

Jon Skeet [C# MVP]

tony obrien said:
In this particular case I use them interchangeably since I created a DLL
from a single Class with nothing but private variables and public
Properties and Methods.... in my mind the Class is the DLL is the Class.

sorry for the confusion.

No problem - but I think it's worth keeping the difference clear in
your head (and in your code and comments) as you never know when you'll
need another class in the same assembly.
Recently I tried bringing that class (that created the DLL) into my test
program and it still does not operate after a 2nd or 3rd thread is begun...
so perhaps I have some deeper issues going on than I thought.

I am trying to get to the smallest thing that I know has the problem.

I'm sure that when we've got a small sample we'll be able to make
progress.
 
T

tony obrien

Hi Jon, (I very much appreciate your taking the time and energy to help
me thru this !)


I have been able to at least determine how the problem exhibits itself...
the very bottom has this explanation.

Below are some snippets to give you an idea of how this load tester
client operates....(and yes I have left out gobs of code as to not bore
(overwhelm !) you... but remember this all works as a single instance so
I propose that it is in the 'multithreaded-ness' of it.)


------- IN MAIN:

'Create a new instance of the tcp interface class
aSession = New serviceConnection

'create a new thread
serverListenerThread = New Threading.Thread(AddressOf
aSession.startThisThread)

'I then start the thread....
serverListenerThread.Start()


------ IN THE SERVICECONNECTION CLASS:

=====================================
Private clientService as TCPClient
Private Event OnLineReceived(ByVal sender As serviceConnection, ByVal
Data() As Byte, ByVal theBytesReadCount As Integer)

=====================================
Public Sub StartThisThread ()

' Create an event handler to allow this serviceconnection class to
communicate
AddHandler OnLineReceived, AddressOf OnLineReceivedService

Try
clientService = New TcpClient(myServerNameStr$,
mSessionPortNumber)

clientService.GetStream.BeginRead(readBuffer, 0,
READ_BUFFER_SIZE, AddressOf ServiceStreamReceiver, Nothing)
SOM = True

Catch Ex As Exception
mlastErrorString = Ex.Message
Exit Sub
End Try

'Now I sit in a loop asking the SERVER for various services


======================================
Private Sub ServiceStreamReceiver(ByVal ar As IAsyncResult)

Try
' Ensure that no other threads try to use the stream at the
same time.
SyncLock client.GetStream
' Finish asynchronous read into readBuffer and get number
of bytes read.
LCBytesRead = client.GetStream.EndRead(ar)
End SyncLock

RaiseEvent OnLineReceived(Me, readBuffer, LCBytesRead)

' Ensure that no other threads try to use the stream at the
same time.
SyncLock client.GetStream
' Start a new asynchronous read into readBuffer.
LCBytesRead = 0
client.GetStream.BeginRead(readBuffer, 0,
READ_BUFFER_SIZE, AddressOf ServiceStreamReceiver, Nothing)
End SyncLock

Catch e As Exception

End Try
End Sub
======================================

Private Sub OnLineReceivedService(ByVal thisServiceConnection As
serviceConnection, ByVal data() As Byte, ByVal theBytesReadCount As
Integer)

'This is the EVENT raised by ServiceStreamReceiver above....

'It gets passed the "instance" of the connection, the bytecount and
data... and this routine operates on the data.


======================================
======================================
======================================

OK, so what happens is that when I start the 2nd or 3rd thread the
OnLineReceivedService callback will get passed the "wrong instance" on
some response message that was received (recall that there are supposedly
distinct "thisServiceConnection" classes created and "started"...) and so
some instance is waiting for a response it never gets... and the instance
that does get passed throws the message away because it wasn't meant for
him.

This implies that the "wrong" instance of ServiceStreamHandler is being
called... perhaps the TCP.net stuff I am using does not allow me to do
what I am trying to do?

regards,
tob
 
N

Nick Malik [Microsoft]

With all due respect, Tony, do you have multiple threads each listening for
data on the same TCP port?

If this were the case, I fail to see how you could PREVENT contention.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
T

tony obrien

With all due respect, Tony, do you have multiple threads each
listening for data on the same TCP port?

If this were the case, I fail to see how you could PREVENT contention.

Hi Nick,

Well,er, yeah but (ye old "yeah butt" !)

I was trying to mimic what a web browser does... my thought was that I
"publish" a known TCP port number (in this case 10,000)... clients connect
to that port number, the SERVER creates a listener for this new connection
in a new thread and starts that thread, then goes back to waiting for a new
connection on 10,000.

My understanding was that the TCP stack magically re-casts the "accepted"
client into a new internal port number and carries the conversation on
(somehow) correctly all the while. And to me this is akin to magic, but
how else *could* a server operate (such as a web browser with ONE KNOWN
port #80.)

Your thoughts?
tob
 
J

Jon Skeet [C# MVP]

tony obrien said:
Hi Jon, (I very much appreciate your taking the time and energy to help
me thru this !)

I have been able to at least determine how the problem exhibits itself...
the very bottom has this explanation.

Below are some snippets to give you an idea of how this load tester
client operates....(and yes I have left out gobs of code as to not bore
(overwhelm !) you... but remember this all works as a single instance so
I propose that it is in the 'multithreaded-ness' of it.)

Well, it's still very hard to actually reproduce it without a complete
application. You shouldn't need *very* much code - just enough to
connect to the server and, say, make the server echo whatever the
client writes to it.
 
T

tony obrien

Well, it's still very hard to actually reproduce it without a complete
application. You shouldn't need *very* much code - just enough to
connect to the server and, say, make the server echo whatever the
client writes to it.

Hi Jon,

Yipee ! I have discovered the error of my ways.

As you originally pointed out it was a matter of "scope".

I was able to discern that there were 3 (helper) classes being brought into
existance outside the scope of the thread trying to communicate... and it
was THEIR data that would occasionally get squashed.

I actually did what you suggested and kept taking parts away until adding
back the "last part" caused the breakage. And this lead me to discover
there were 2 other parts that had a similar issue.

I can now run MANY clients into the server and they all keep themselves
straight (and the server is a blur ;<>)

Thanks and regards,
tob
 
J

Jon Skeet [C# MVP]

tony obrien said:
Yipee ! I have discovered the error of my ways.

Hooray :)
As you originally pointed out it was a matter of "scope".

I was able to discern that there were 3 (helper) classes being brought into
existance outside the scope of the thread trying to communicate... and it
was THEIR data that would occasionally get squashed.

I actually did what you suggested and kept taking parts away until adding
back the "last part" caused the breakage. And this lead me to discover
there were 2 other parts that had a similar issue.

That's the genius part of me insisting on complete programs - it means
that half the time I don't need to figure out anything myself :)
I can now run MANY clients into the server and they all keep themselves
straight (and the server is a blur ;<>)

Cool. Glad you got it sorted.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top