470,815 Members | 1,313 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,815 developers. It's quick & easy.

ActiveX / Threads question

Short question:
What's the difference between SingleUse and MultiUse ?

Long question:
I've been writing some sample code to see how different Instancing
values and threading models work. I tried all main combinations of
Instancing (Multiuse/Singleuse) and of Threading models (per
object/pool). Here's what I found:

MultiUse - Thread per Object
One new object for each request

SingleUse - Thread per Object
One new object for each request

MultiUse - Thread Pool (w/ 1 thread)
One object reused by all requests

SingleUse - Thread Pool (w/ 1 thread)
One new object for each request

The SU seems to be 100% superfluous: not only changing thread model
does not change the way it works, but whatever it does, it's exaclty
what MU does!

In order to test, I have created an ActiveXEXE with a form (frmTest)
and two classes (instancing is MU for one and SU for the other), both
have the same public method:

Public Sub Show(ByVal FormCaption As String, Top As Long, Left As
Long)
With frmTest
'First time show
If Not .Visible Then
.Top = Top
.Left = Left
.Visible = True
DoEvents
End If
.Caption = .Caption & FormCaption
End With
End Sub

The client calls this with something like:

Dim MUServ As New ActiveXServerEXE.MultiUseClass
Call MUServ.Show(Index & " - " & Time, Top, Left + Width)

[Don't worry about the Top/Left stuff, it's irrelevant for this
discussion]

Can anybody shed some light on this topic once and for all ?

Thanks!
AK
Jul 17 '05 #1
8 4403

"AnalogKid" <AnalogKid17@(more_than_warm)mail.com> wrote in message
news:mq********************************@4ax.com...
| Short question:
| What's the difference between SingleUse and MultiUse ?
|
| Long question:
| I've been writing some sample code to see how different Instancing
| values and threading models work. I tried all main combinations of
| Instancing (Multiuse/Singleuse) and of Threading models (per
| object/pool). Here's what I found:
|
| MultiUse - Thread per Object
| One new object for each request

Each object is created by the same instance of the activex.exe. If there
is a module in the activex.exe with public data, all of the objects
could see that data, even if they are created by different applications.
Each object has its own thread.

|
| SingleUse - Thread per Object
| One new object for each request
|
Each object is created by a new instance of the activex.exe. Each object
can see public data only in its own instance of the activex.exe. Each
object has its own thread (actually, each has its own process).

| MultiUse - Thread Pool (w/ 1 thread)
| One object reused by all requests
|

Not quite. Actually nearly the same as MultiUse Thread/Object, except
that all the objects will be serviced using the same thread. You can
still create multiple, discreet objects.

| SingleUse - Thread Pool (w/ 1 thread)
| One new object for each request
|
|"changing thread model does not change the way it works"

Correct. The threading option applies only to MultiUse, not to
SingleUse, so this is identical to SingleUse - Thread/Object.

Clear as mud? :-)
Jul 17 '05 #2
On Mon, 26 Jul 2004 18:45:39 -0700, "Steve Gerrard"
<no*************@comcast.net> wrote:

"AnalogKid" <AnalogKid17@(more_than_warm)mail.com> wrote in message
news:mq********************************@4ax.com.. .
| Short question:
| What's the difference between SingleUse and MultiUse ?
|
| Long question:
| I've been writing some sample code to see how different Instancing
| values and threading models work. I tried all main combinations of
| Instancing (Multiuse/Singleuse) and of Threading models (per
| object/pool). Here's what I found:
|
| MultiUse - Thread per Object
| One new object for each request

Each object is created by the same instance of the activex.exe. If there
is a module in the activex.exe with public data, all of the objects
could see that data, even if they are created by different applications.
Each object has its own thread.

Would you be kind enough to post some sample code to prove this ? I
modified my code to read/write a public property and each object
created has its own copy. When you say public data I assume you meana
public property in the MultiUse class, correct ?
|
| SingleUse - Thread per Object
| One new object for each request
|
Each object is created by a new instance of the activex.exe. Each object
can see public data only in its own instance of the activex.exe. Each
object has its own thread (actually, each has its own process).

Again, I get the same result. No shared data.
| MultiUse - Thread Pool (w/ 1 thread)
| One object reused by all requests
|

Not quite. Actually nearly the same as MultiUse Thread/Object, except
that all the objects will be serviced using the same thread. You can
still create multiple, discreet objects.

| SingleUse - Thread Pool (w/ 1 thread)
| One new object for each request
|
|"changing thread model does not change the way it works"

Correct. The threading option applies only to MultiUse, not to
SingleUse, so this is identical to SingleUse - Thread/Object.

Clear as mud? :-)

Thank you for trying to explain this to me, I beg you not to give
up... I think part of the problem is in terminology. The way I see it
there is 1 ActiveX that contains n Classes. Each class can be
instantiated x times to create x copies of itself (objects).

On top of this you talk about instances of the ActiveX, do you mean
instance of one of the ActiveX Classes ?

Thanks
AK

PS: I haven't even asked questions about Apartment and Single threaded
in DLLs yet... Hopefully that will be easier once EXEs are assimiltaed
:-)
Jul 17 '05 #3

"AnalogKid" <AnalogKid17@(more_than_warm)mail.com> wrote in message
news:9n********************************@4ax.com...
| On Mon, 26 Jul 2004 18:45:39 -0700, "Steve Gerrard"
| <no*************@comcast.net> wrote:
|
| >| MultiUse - Thread per Object
| >
| >Each object is created by the same instance of the activex.exe. If
there
| >is a module in the activex.exe with public data, all of the objects
| >could see that data, even if they are created by different
applications.
| >Each object has its own thread.
| >
|
| Would you be kind enough to post some sample code to prove this ? I
| modified my code to read/write a public property and each object
| created has its own copy. When you say public data I assume you meana
| public property in the MultiUse class, correct ?
|

No, by public data I mean in a bas module. Each object instance will
have its own class data, but they can retrieve a "shared" value from the
bas module.

Add this to your activex.exe, and set its project startup property to
sub main:

Public globalStart As Single

Public Sub Main()
globalStart = Timer
End Sub

Then put a public property in your class, along with what you have, like
this:
Public Property GetStart() As Single
GetStart = globalStart
End Property

In your test code, you should be able to see that each object instance
has its own class data, but they all return the same value for GetStart.
It will help if you delay 1 or two seconds between each object creation,
and don't discard any till the test is over. If you look at the process
list in Task Manager while several objects are still alive, you should
see only one copy of your activex.exe loaded.

| >|
| >| SingleUse - Thread per Object
|
| >Each object is created by a new instance of the activex.exe. Each
object
| >can see public data only in its own instance of the activex.exe. Each
| >object has its own thread (actually, each has its own process).
| >
|
| Again, I get the same result. No shared data.

If you do the same thing with this activex.exe, you should discover that
with SingleUse, each object instance has its own class data, but now
each returns a different value for GetStart. If you look at the process
list in Task Manager while several objects are still alive, you should
see that several copies of your activex.exe are loaded.

| Thank you for trying to explain this to me, I beg you not to give
| up... I think part of the problem is in terminology. The way I see it
| there is 1 ActiveX that contains n Classes. Each class can be
| instantiated x times to create x copies of itself (objects).
|
| On top of this you talk about instances of the ActiveX, do you mean
| instance of one of the ActiveX Classes ?
|

Multiple instance of an activex.exe: in task manager, multiple copies of
the exe are loaded in the process list. This is similar to starting up
several copies of Excel or some other program.

Note that threading has nothing to do with instances of objects, or
instances(copies) of the activex.exe getting loaded. Threading is just
about how multiple objects created from a multiuse class do their work -
either by sharing one or more threads, or by each having its own thread
assigned.
Jul 17 '05 #4
On Wed, 28 Jul 2004 19:10:31 -0700, "Steve Gerrard"
<no*************@comcast.net> wrote:

Thanks for your reply, see mine below...

"AnalogKid" <AnalogKid17@(more_than_warm)mail.com> wrote in message
news:9n********************************@4ax.com.. .
| On Mon, 26 Jul 2004 18:45:39 -0700, "Steve Gerrard"
| <no*************@comcast.net> wrote:
|
| >| MultiUse - Thread per Object
| >
| >Each object is created by the same instance of the activex.exe. If there
| >is a module in the activex.exe with public data, all of the objects
| >could see that data, even if they are created by different aapplications.
| >Each object has its own thread.
| >
|
| Would you be kind enough to post some sample code to prove this ? I
| modified my code to read/write a public property and each object
| created has its own copy. When you say public data I assume you meana
| public property in the MultiUse class, correct ?
|

No, by public data I mean in a bas module. Each object instance will
have its own class data, but they can retrieve a "shared" value from the
bas module.

Add this to your activex.exe, and set its project startup property to
sub main:

Public globalStart As Single

Public Sub Main()
globalStart = Timer
End Sub

Then put a public property in your class, along with what you have, like
this:
Public Property GetStart() As Single
GetStart = globalStart
End Property

In your test code, you should be able to see that each object instance
has its own class data, but they all return the same value for GetStart.
It will help if you delay 1 or two seconds between each object creation,
and don't discard any till the test is over. If you look at the process
list in Task Manager while several objects are still alive, you should
see only one copy of your activex.exe loaded.
Steve, I had done a similar test, and while I correctly see one
instance of the MU server and multiple of the SU server in the
processes, I still see one copy of the public data per client, ie each
has its own GetStart value!
| >|
| >| SingleUse - Thread per Object
|
| >Each object is created by a new instance of the activex.exe. Each object
| >can see public data only in its own instance of the activex.exe. Each
| >object has its own thread (actually, each has its own process).
| >
|
| Again, I get the same result. No shared data.

If you do the same thing with this activex.exe, you should discover that
with SingleUse, each object instance has its own class data, but now
each returns a different value for GetStart. If you look at the process
list in Task Manager while several objects are still alive, you should
see that several copies of your activex.exe are loaded.

| Thank you for trying to explain this to me, I beg you not to give
| up... I think part of the problem is in terminology. The way I see it
| there is 1 ActiveX that contains n Classes. Each class can be
| instantiated x times to create x copies of itself (objects).
|
| On top of this you talk about instances of the ActiveX, do you mean
| instance of one of the ActiveX Classes ?
|

Multiple instance of an activex.exe: in task manager, multiple copies of
the exe are loaded in the process list. This is similar to starting up
several copies of Excel or some other program.

Note that threading has nothing to do with instances of objects, or
instances(copies) of the activex.exe getting loaded. Threading is just
about how multiple objects created from a multiuse class do their work -
either by sharing one or more threads, or by each having its own thread
assigned.

This is also hard to prove with test code: both "Thread per Object"
and "Thread Pool" lock creation of new objects when one is busy.

Thanks again for your help!
Jul 17 '05 #5

"AnalogKid" <AnalogKid17@(more_than_warm)mail.com> wrote in message
news:io********************************@4ax.com...
| On Wed, 28 Jul 2004 19:10:31 -0700, "Steve Gerrard"
| <no*************@comcast.net> wrote:
|
| >
| >Add this to your activex.exe, and set its project startup property to
| >sub main:
| >
| >Public globalStart As Single
| >
| >Public Sub Main()
| > globalStart = Timer
| >End Sub
| >

The above must be in a .bas module, not in a class definition.

| >Then put a public property in your class, along with what you have,
like
| >this:
| >Public Property GetStart() As Single
| > GetStart = globalStart
| >End Property
| >
| >In your test code, you should be able to see that each object
instance
| >has its own class data, but they all return the same value for
GetStart.
| >It will help if you delay 1 or two seconds between each object
creation,
| >and don't discard any till the test is over. If you look at the
process
| >list in Task Manager while several objects are still alive, you
should
| >see only one copy of your activex.exe loaded.
| >
| Steve, I had done a similar test, and while I correctly see one
| instance of the MU server and multiple of the SU server in the
| processes, I still see one copy of the public data per client, ie each
| has its own GetStart value!
|

I know for a fact this works for a MultiUse class, so you must have
something wrong. Was the public data you checked stored in a .bas
module, not a class?
Jul 17 '05 #6
Steve,
Sorry for the interruption (short vacation...) I think I undesrstood
at least part of the problem. See below:

On Thu, 29 Jul 2004 18:42:04 -0700, "Steve Gerrard"
<no*************@comcast.net> wrote:
| >
| Steve, I had done a similar test, and while I correctly see one
| instance of the MU server and multiple of the SU server in the
| processes, I still see one copy of the public data per client, ie each
| has its own GetStart value!
|
I know for a fact this works for a MultiUse class, so you must have
something wrong. Was the public data you checked stored in a .bas
module, not a class?

The problem is that my Threading Model was set on Thread per Object,
as opposed to the default, Thread Pool 1. Now I can see one copy of
global data for all instantiations.

This means that sharing the same global data is actually a matter of
threads, it's not a prerogative of *all* MultiUse classes, but only
when all clients communicate on the same thread (ie, Thread Pool w/ 1
thread). As soon as you have multiple threads or Threads per Object
(my previous test environment), even global data is duplicated for
each new object created.

Now that we have determined this, my reviewed summary of permutations
looks like this:

MultiUse - Thread per Object
1 process in TaskManager
One new object for each request (each w/ its own data)

SingleUse - Thread per Object
Multiple processes in TaskManager
One new object for each request (each w/ its own data)

MultiUse - Thread Pool (w/ 1 thread)
1 process in TaskManager
One object reused by all requests (global data is in common)

SingleUse - Thread Pool (w/ 1 thread)
Multiple processes in TaskManager
One new object for each request (each w/ its own data)

In conclusion:
a) For SingleUse the Thread Model box should be grayed out, being able
to choose between TpO and TP is just useless confusion. Even with
Thread Pool 1, all created objects work on different threads.
b) MultiUse with a 1 thread pool allows to share global data
c) MultiUse with TpO is like SingleUse, except that there is always
one process for MUs while SUs create one every time a class is
instantiated.

Hopefully the above is correct... can anybody confirm ?

Many thanks to Steve!
AK

Jul 17 '05 #7
comments in line:

"AnalogKid" <AnalogKid17@(more_than_warm)mail.com> wrote in message
news:pn********************************@4ax.com...
| Steve,
| Sorry for the interruption (short vacation...) I think I undesrstood
| at least part of the problem. See below:

I'm doing one next week. I believe all vacations turn out to be short.
:)

| Now that we have determined this, my reviewed summary of permutations
| looks like this:

In all of the below, your use of the word object is confusing. An object
is an instance of a class, which is distinct from an instance of the
..exe in task manager. In all of the below, you get a new object for each
request, never the same object.

| MultiUse - Thread per Object
| 1 process in TaskManager
| One new object for each request (each w/ its own data)

I confirm this. It seems a little suprising, but there is no shared
global data in this case, even though there is only one instance of the
..exe loaded.

| SingleUse - Thread per Object
| Multiple processes in TaskManager
| One new object for each request (each w/ its own data)

And no global data in common. Each object comes from a different .exe
instance in task manager.

| MultiUse - Thread Pool (w/ 1 thread)
| 1 process in TaskManager
| One object reused by all requests (global data is in common)

Thats the language I don't like. Each object is still a distinct object,
with its own class data. Only the global data that is not part of a
class is common to them.

| SingleUse - Thread Pool (w/ 1 thread)
| Multiple processes in TaskManager
| One new object for each request (each w/ its own data)

Yup. SingleUse is SingleUse .

| In conclusion:

| a) For SingleUse the Thread Model box should be grayed out, being able
| to choose between TpO and TP is just useless confusion. Even with
| Thread Pool 1, all created objects work on different threads.

Correct. At least it is documented as such. The only reason I can see
for it is that the threading model applies to the whole project, and it
is possible to have both SingleUse and MultiUse classes in the same exe.
Figuring out what happens with that can be your next project. :)

| b) MultiUse with a 1 thread pool allows to share global data

Right.

| c) MultiUse with TpO is like SingleUse, except that there is always
| one process for MUs while SUs create one every time a class is
| instantiated.
|

That seems to be right, odd as it is. Why would you go with SU, if
MU+TPO gets you the same isolation with less loading up of duplicate
exes?
Jul 17 '05 #8
On Wed, 4 Aug 2004 20:05:34 -0700, "Steve Gerrard"
<my********@comcast.net> wrote:
comments in line:

"AnalogKid" <AnalogKid17@(more_than_warm)mail.com> wrote in message
news:pn********************************@4ax.com.. .
| Steve,
| Sorry for the interruption (short vacation...) I think I undesrstood
| at least part of the problem. See below:

I'm doing one next week. I believe all vacations turn out to be short.
:)

| Now that we have determined this, my reviewed summary of permutations
| looks like this:

In all of the below, your use of the word object is confusing. An object
is an instance of a class, which is distinct from an instance of the
.exe in task manager. In all of the below, you get a new object for each
request, never the same object.

| MultiUse - Thread per Object
| 1 process in TaskManager
| One new object for each request (each w/ its own data)

I confirm this. It seems a little suprising, but there is no shared
global data in this case, even though there is only one instance of the
.exe loaded.

| SingleUse - Thread per Object
| Multiple processes in TaskManager
| One new object for each request (each w/ its own data)

And no global data in common. Each object comes from a different .exe
instance in task manager.

| MultiUse - Thread Pool (w/ 1 thread)
| 1 process in TaskManager
| One object reused by all requests (global data is in common)

Thats the language I don't like. Each object is still a distinct object,
with its own class data. Only the global data that is not part of a
class is common to them.
Actually my language was correct; my understanding was wrong, though.
I was actually under the impression that all objects created would
point to the same one, but I see now that they are all distinct ones.
| SingleUse - Thread Pool (w/ 1 thread)
| Multiple processes in TaskManager
| One new object for each request (each w/ its own data)

Yup. SingleUse is SingleUse .

| In conclusion:

| a) For SingleUse the Thread Model box should be grayed out, being able
| to choose between TpO and TP is just useless confusion. Even with
| Thread Pool 1, all created objects work on different threads.

Correct. At least it is documented as such. The only reason I can see
for it is that the threading model applies to the whole project, and it
is possible to have both SingleUse and MultiUse classes in the same exe.
Figuring out what happens with that can be your next project. :)

| b) MultiUse with a 1 thread pool allows to share global data

Right.

| c) MultiUse with TpO is like SingleUse, except that there is always
| one process for MUs while SUs create one every time a class is
| instantiated.
|

That seems to be right, odd as it is. Why would you go with SU, if
MU+TPO gets you the same isolation with less loading up of duplicate
exes?


Jul 17 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

18 posts views Thread by DartmanX | last post: by
7 posts views Thread by Jarod_24 | last post: by
5 posts views Thread by Yeti | last post: by
6 posts views Thread by hufaunder | last post: by
2 posts views Thread by =?Utf-8?B?Sm9obiBG?= | last post: by
1 post views Thread by Jialiang Ge [MSFT] | last post: by
reply views Thread by mihailmihai484 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.