473,326 Members | 2,136 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

System.Thread and multiple method calls

Hi group,

I am relatively new to C# (although I have a lot of programming
excperience in other languages like Java and C). Currently I am
searching for a solution to this problem:

Suppose you have 3 methods A, B and C. All of them shall be run
threaded (I/O tasks) and one after another. I can create a thread and
schedule one method just like:

Thread t = new Thread(A);

But how do I add the other 2 methods? Can this be done somehow with
the .NET Library classes or do I have to create my own "Thread-Method-
Manager" for this purpose? I also would like to add and remove the
methods being executed dynamically.

Thansk for your ideas!

Regards,
Paul
Dec 25 '07 #1
16 8338

"Paul Schwann" <pa**********@gmail.comwrote in message
news:66**********************************@e23g2000 prf.googlegroups.com...
Hi group,

I am relatively new to C# (although I have a lot of programming
excperience in other languages like Java and C). Currently I am
searching for a solution to this problem:

Suppose you have 3 methods A, B and C. All of them shall be run
threaded (I/O tasks) and one after another. I can create a thread and
schedule one method just like:

Thread t = new Thread(A);

But how do I add the other 2 methods? Can this be done somehow with
the .NET Library classes or do I have to create my own "Thread-Method-
Manager" for this purpose? I also would like to add and remove the
methods being executed dynamically.

Thansk for your ideas!

Regards,
Paul
Hi Paul,

Not so sure about Java and C, but in every language I've ever worked in a
thread has a single starting point and linear execution path, just like the
"main" program thread. So, in your case, if you want to execute methods A,
B, and C, you would need to create a new method D that calls A, B, and C and
use method D as your thread proc. You can, of course, pass parameters to
method D to identify which other methods to be executed.

I suppose you *could* implement some sort of message pump (like the "main"
program thread usually has) and dynamically execute methods based on
messages, but that seems like it may be overkill, depending on what you are
trying to accomplish.

Scott

Dec 26 '07 #2
Hi Scott,

thanks for your reply! Implementing such a method D by myself is what
I more or less will do now. I just thought how nice it would be based
on some kind of delegates... Like

Thread t = new Thread();
t.executeThis += A;
t.start();
....
t.executeThis += B;
....
t.executeThis += C;
....
t.executeThis -= A;

.... You get the idea... :-)

Regards,
Paul
Dec 26 '07 #3
Scott Roberts <sr******@no.spam.here-webworks-software.comwrote:
Not so sure about Java and C, but in every language I've ever worked in a
thread has a single starting point and linear execution path, just like the
"main" program thread. So, in your case, if you want to execute methods A,
B, and C, you would need to create a new method D that calls A, B, and C and
use method D as your thread proc. You can, of course, pass parameters to
method D to identify which other methods to be executed.
Yup. One "wrinkle" to .NET is that what you pass in when you create a
thread is a delegate - and delegates can have multiple targets. I've
*never* used ThreadStart in this way before, but it will work. It's
pretty odd...

using System;
using System.Threading;

class Test
{
static void Main()
{
ThreadStart start = null;

start += A;
start += B;
start += C;

new Thread(start).Start();
}

static void A()
{
Console.WriteLine ("A");
}

static void B()
{
Console.WriteLine ("B");
}

static void C()
{
Console.WriteLine ("C");
}
}

Note that you can't add to the list of methods to execute after you've
started the thread though.
I suppose you *could* implement some sort of message pump (like the "main"
program thread usually has) and dynamically execute methods based on
messages, but that seems like it may be overkill, depending on what you are
trying to accomplish.
Again, I agree. Fortunately if the OP *does* need to do this, it's not
too hard to do with a producer/consumer queue.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Dec 26 '07 #4
Paul Schwann <pa**********@gmail.comwrote:
thanks for your reply! Implementing such a method D by myself is what
I more or less will do now. I just thought how nice it would be based
on some kind of delegates... Like
<snip>

Yup, see my recent post for a complete example. You should probably
comment this in your code, however - it's not a common pattern. (Quite
a neat one though.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Dec 26 '07 #5
Hi,
You are saying that the 3 methods needs to be run one after the other, what
if you create a new method (can be anonymous) that call the 3 methods?

void DoIt()
{
A();
B();
C();
}
and then is that method the one that you start the thread with?
--
Ignacio Machin
http://www.laceupsolutions.com
Mobile & warehouse Solutions.
"Scott Roberts" <sr******@no.spam.here-webworks-software.comwrote in
message news:%2****************@TK2MSFTNGP05.phx.gbl...
>
"Paul Schwann" <pa**********@gmail.comwrote in message
news:66**********************************@e23g2000 prf.googlegroups.com...
>Hi group,

I am relatively new to C# (although I have a lot of programming
excperience in other languages like Java and C). Currently I am
searching for a solution to this problem:

Suppose you have 3 methods A, B and C. All of them shall be run
threaded (I/O tasks) and one after another. I can create a thread and
schedule one method just like:

Thread t = new Thread(A);

But how do I add the other 2 methods? Can this be done somehow with
the .NET Library classes or do I have to create my own "Thread-Method-
Manager" for this purpose? I also would like to add and remove the
methods being executed dynamically.

Thansk for your ideas!

Regards,
Paul

Hi Paul,

Not so sure about Java and C, but in every language I've ever worked in a
thread has a single starting point and linear execution path, just like
the "main" program thread. So, in your case, if you want to execute
methods A, B, and C, you would need to create a new method D that calls A,
B, and C and use method D as your thread proc. You can, of course, pass
parameters to method D to identify which other methods to be executed.

I suppose you *could* implement some sort of message pump (like the "main"
program thread usually has) and dynamically execute methods based on
messages, but that seems like it may be overkill, depending on what you
are trying to accomplish.

Scott

Dec 26 '07 #6
Hi,
--
Ignacio Machin
http://www.laceupsolutions.com
Mobile & warehouse Solutions.
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Yup. One "wrinkle" to .NET is that what you pass in when you create a
thread is a delegate - and delegates can have multiple targets. I've
*never* used ThreadStart in this way before, but it will work. It's
pretty odd...
I have never though of this. Of course as ThreadStart is a delegate you can
do it. I wander what would happen if one method throw an exception ....
Dec 26 '07 #7


"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
[Side point - Ignacio, all your posts end up with a signature before
all of the quoted text. That means when I start to reply, all I end up
with is "Hi". Could you either remove the signature separator or make
sure it ends up after the body?]

Sorry for that, no idea why OE place the signature at the top instead of at
the botton of the message. Will have to dig around to see if I can change it
somewhere.

Ignacio Machin
http://www.laceupsolutions.com
Mobile & warehouse Solutions.
Dec 26 '07 #8
Hi Ignacio,

basically, you are right:
>
You are saying that the 3 methods needs to be run one after the other, what
if you create a new method (can be anonymous) that call the 3 methods?

void DoIt()
{
* * A();
* * B();
* * C();

}
But I need a way t configure the "three" methods such that I can say
when (and when not) they run. I want to select them during runtime and
thus, need something more dynamic than just a function D().

If you have any ideas how to do this nicely, please let me know!

Regards,
Paul
Dec 26 '07 #9
Hi Pete and all the others,

thanks a lot for your valuable input! Although Jon's solution is
almost perfect, it does'nt work for me. I have to be able to add and
remove any of the A, B, C, ... functions form the delegate while the
thread is *already running*. I think I will implement my own way of
doing this. Here is my first idea (sort of Java/Pseudo code):

class MyThreadManager extends Thread {
List<RunnableexecuteThis;

public void run() {
for (runnable in executeThis) {
runnable.run();
}
}

synchronized addExecutable(Runnable r) {...}
synchronized removeExecutable(Runnable r) {...}
}

Just an idea.... :-)

Regards,
Paul

Dec 27 '07 #10
On Thu, 27 Dec 2007 01:53:16 -0800, Paul Schwann <pa**********@gmail.com>
wrote:
Hi Pete and all the others,

thanks a lot for your valuable input! Although Jon's solution is
almost perfect, it does'nt work for me. I have to be able to add and
remove any of the A, B, C, ... functions form the delegate while the
thread is *already running*. I think I will implement my own way of
doing this. Here is my first idea (sort of Java/Pseudo code): [snip]
The code you posted is not far off from the producer/consumer suggestion.
However, one thing you're going to run into is the problem of modifying a
List<instance while you've got an enumerator operating on it.

You could address that by enumerating by an index that's stored not as a
local variable but a member variable of the implementation class, so that
it can be adjusted to account for methods removed during execution.

The other issue you'll have to solve is what to do when the client code
tries to remove a method that's already running. Simplest would be to
just ignore that, let the method be removed from the list without
affecting the current execution of it. An alternative would be to make
the methods cancellable, with removal causing a cancellation, but since
that would complicate an already-complicated design, I think it'd be
better if you can do without that feature.

I do think you should consider carefully whether you really must have the
behavior you're asking about. There's nothing wrong with it as long as
that's really the most straightforward and clean way to accomplish
whatever it is you're trying to accomplish. But it's definitely an
unusual request, and my experience has been that many (but not all, of
course) unusual requests represent a design choice that could have been
made differently, in a way that leads to a simpler implementation.

This latter point is especially true when the unusual request involves
creating a complicated situation such as this one. A straight
producer/consumer design wouldn't be exactly what you've asked for, but it
would be much simpler architecturally. Neither are particularly difficult
to implement, but conceptually having a mutable list of execution methods
that can change while it's being enumerated is at the very least
complicated, and at worst could lead to puzzling or subtle bugs that are
very dependent on the timing of the code elsewhere. You should be sure
that this is a maintenance cost that is worth whatever advantage that
design has for you.

Pete
Dec 27 '07 #11
Hi Peter,

thanks a lot for your detailed answer. I appreciate it a lot! I am
aware of the fact that the request I have is somewhat unusal. This is
due to the implementation of the underlying library which will be
called by all of those A, B, C... methods I mentioned.

The situation is such that this library is not thread safe in any way.
Thus, only one thread shall access it at at time.

On the other hand we have those A, B, C methods which belong to
different parts of the application and do different things of course.
Nevertheless, they all access this library sooner or later.

All these methods A, B, C... do repeating things once or twice a
second. In a perfect world, I would just put each of these functions
in a timer and I am done. But I cannot due to the lack of thread
safety and inability of reentranace of the library methods.

---

About my little code snippet: Of cousre, reading/writing of this
List<must be thread safe. Thus, my idea is that in a synchronized
part of the code, the list is copied and this copy is used for the
enumaration.
Thus, the original List<can be manipulated at any time except for
the very short time period required to create the copy.
Once a method is removed or added to the List<>, it will executed the
NEXT time the for.. loop runs. It has no impact on the current loop-
run. This behavior is exceptable for my application.

---

If you have any comments on this or a better suggestion to solve it, I
would like to hear it and discuss it!

Regards,
Paul
Dec 28 '07 #12
Hi Peter,

thanks a lot for your detailed answer. I appreciate it a lot! I am
aware of the fact that the request I have is somewhat unusal. This is
due to the implementation of the underlying library which will be
called by all of those A, B, C... methods I mentioned.

The situation is such that this library is not thread safe in any way.
Thus, only one thread shall access it at at time.

On the other hand we have those A, B, C methods which belong to
different parts of the application and do different things of course.
Nevertheless, they all access this library sooner or later.

All these methods A, B, C... do repeating things once or twice a
second. In a perfect world, I would just put each of these functions
in a timer and I am done. But I cannot due to the lack of thread
safety and inability of reentranace of the library methods.

---

About my little code snippet: Of cousre, reading/writing of this
List<must be thread safe. Thus, my idea is that in a synchronized
part of the code, the list is copied and this copy is used for the
enumaration.
Thus, the original List<can be manipulated at any time except for
the very short time period required to create the copy.
Once a method is removed or added to the List<>, it will executed the
NEXT time the for.. loop runs. It has no impact on the current loop-
run. This behavior is exceptable for my application.

---

If you have any comments on this or a better suggestion to solve it, I
would like to hear it and discuss it!

Regards,
Paul
Dec 28 '07 #13
On Fri, 28 Dec 2007 12:01:41 -0800, Paul Schwann <pa**********@gmail.com
wrote:
Hi Peter,

thanks a lot for your detailed answer. I appreciate it a lot! I am
aware of the fact that the request I have is somewhat unusal. This is
due to the implementation of the underlying library which will be
called by all of those A, B, C... methods I mentioned.

The situation is such that this library is not thread safe in any way.
Thus, only one thread shall access it at at time.
There are other ways to accomplish that. Better ones, IMHO.
On the other hand we have those A, B, C methods which belong to
different parts of the application and do different things of course.
Nevertheless, they all access this library sooner or later.
It's true that serializing the calls to those methods will ensure
synchronization of access to the library. However, your description
implies that accessing the library isn't _all_ that those methods are
doing, and so of course if you serialize the methods you fail to take
advantage of any parallelism that might otherwise exist between the
methods (e.g. if two or more are doing i/o, or if you have a computer
system with more than one CPU core).

It would be simplest if you could simply add the synchronization to the
methods being called. However, I understand that it's possible those
methods might have numerous calls to the library written into the code and
it would be tedious and error-prone to try to synchronize each and every
call. If that's the case, then the better alternative would be to modify
the library so that it's thread-safe. Assuming that you don't have
control over the library itself, the way to do this would be to create a
wrapper class that accesses the library, and which includes the
synchronizing code itself, locking around each call into the library.

By the way, by "synchronizing" I just mean any mechanism available in .NET
for accomplishing this. A very common scenario is to create a plain
"object" type instance (e.g. "object _objLock = new object()") and use
that as the parameter for a "lock()" statement, with the call to the
library inside the block protected by the lock.
[...]
About my little code snippet: Of cousre, reading/writing of this
List<must be thread safe. Thus, my idea is that in a synchronized
part of the code, the list is copied and this copy is used for the
enumaration.
Thus, the original List<can be manipulated at any time except for
the very short time period required to create the copy.
Once a method is removed or added to the List<>, it will executed the
NEXT time the for.. loop runs. It has no impact on the current loop-
run. This behavior is exceptable for my application.
I don't understand. If that behavior is acceptable for the application,
then why not just have a ThreadStart delegate that can be modified by code
wanting to add or remove these methods, and then use that delegate when
you start the thread? This would be a variation on the implementation Jon
suggests, except that instead of creating the delegate in the method that
starts the thread, you'd keep the delegate variable somewhere more
accessible to the code that wants to add or remove methods.

Delegates are already immutable and behave pretty much like what you've
suggested above (a new copy is made each time something's added or
removed, with just the reference being replaced) so if you just provide a
method to lock around the changes to the delegate, you'll be assured that
when you go to use the delegate it's in a usable state and won't change
during the execution of the thread itself.

Of course, this is very similar to what an event does, and you may find
that it works even better to define the delegate variable as an event, and
pass a copy of that event variable as the ThreadStart delegate. For
example:

event ThreadStart LibraryAccess;

void Start()
{
Thread thread = new Thread(LibraryAccess);

thread.Start();
}

Then you'd just use syntax like this:

LibraryAccess += A;
LibraryAcdess += B;

LibraryAccess -= A;
// etc.

To add and remove the methods. Each time the thread is created, it would
get the current copy of the event as a ThreadStart delegate and use that
to execute the thread.

Of course, if you are running these methods on a relatively frequent
basis, it may make sense to use the thread pool rather than creating a new
thread each time. But I think if they only get run every couple of
seconds and the execution itself isn't extremely brief, creating a
dedicated thread is probably okay.

Of course, all of this latter discussion assumes that you cannot make the
library thread-safe and must serialize the execution of these methods. As
I mentioned above, I think a better approach would be in fact to not
serialize the execution of the methods (possibly using the thread pool to
execute them) and make the library thread-safe somehow, even if that means
writing a whole new class that wraps the library and synchronizes access
to it for you.

Pete
Dec 28 '07 #14
Hi there,

I had the chance to code something which apparently does what I want
it to do :-) Now, I have a couple of questions where I cannot find
answers. But the code first:

using System;

namespace test {
public class Test {
public static void Main() {

Console.WriteLine(System.Reflection.Assembly.GetEx ecutingAssembly().Location);

new Test();
}

private Test() {
ThreadManager tm = new ThreadManager();
tm.e = A;

System.Threading.Thread.Sleep(500);

tm.e -= A;

System.Threading.Thread.Sleep(500);

tm.e += A;
tm.e += B;

System.Threading.Thread.Sleep(500);

tm.e += C;

System.Threading.Thread.Sleep(500);

tm.e -= A;
tm.e -= B;

System.Threading.Thread.Sleep(500);

tm.dispose();
}

private void A() {
Console.Write("A");
}

private void B() {
Console.Write("B");
}

private void C() {
Console.Write("C");
}
}

public class ThreadManager {
private bool disposed;

public delegate void execute();

public execute e;

public ThreadManager() {
disposed = false;
System.Threading.Thread t = new
System.Threading.Thread(run);
t.Start();
}

private void run() {
while (!disposed) {
if (e != null) {
e();
}
}
}

public void dispose() {
disposed = true;
}
}
}

The class ThreadManager is the heart of this little example above. It
basically uses a delegate to handle all the desired methods being
called. And here are the questions:

1. Is adding and removing methods from the delegate thread safe?
2. If not, how do I synchronize this tm.e += ... and tm.e -=
operations?

Thanks for any advices!

Regards,
Paul
Jan 2 '08 #15
Paul Schwann <pa**********@gmail.comwrote:

<snip>
The class ThreadManager is the heart of this little example above. It
basically uses a delegate to handle all the desired methods being
called. And here are the questions:

1. Is adding and removing methods from the delegate thread safe?
Sort of. The thing is, you never actually add a method to an existing
delegate - you replace an existing one.
2. If not, how do I synchronize this tm.e += ... and tm.e -=
operations?
Turn the public field (argh!) into an event, and make the event itself
thread-safe, as per
http://pobox.com/~skeet/csharp/threads/lockchoice.shtml

Public writable fields are always going to have thread-safety issues.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Jan 2 '08 #16
On Wed, 02 Jan 2008 01:31:41 -0800, Paul Schwann <pa**********@gmail.com
wrote:
[...]
The class ThreadManager is the heart of this little example above. It
basically uses a delegate to handle all the desired methods being
called. And here are the questions:

1. Is adding and removing methods from the delegate thread safe?
Yes and no. In the code you posted, all of the changes to the delegate
are done in a single thread. That's safe.

But no, if you are changing the delegate from multiple threads, then two
different threads could race while trying to change the delegate. The
thread that loses the race actually wins, as its copy of the new delegate
is the one that will get assigned, overwriting the change of the other
thread.
2. If not, how do I synchronize this tm.e += ... and tm.e -=
operations?
Well, this is why I suggested in my previous post that in this case, you
might find it useful to just use an event as the ThreadStart delegate. It
already has this thread-safety built in.

That said, it's easy enough to do yourself if you want. As I also wrote
in that same post, you can use the lock() statement to protect accesses
that change the delegate, ensuring that any thread changing the delegate
can always take into account the changes some other thread is making.

Finally, the code you posted has a bug:

private void run() {
while (!disposed) {
if (e != null) {
e();
}
}
}

You need to store the value of "e" before checking it for null, or put a
lock around the if() statement. Otherwise, "e" could be set to null
between the time you check it and the time you use it.

For example:

private void run() {
while (!disposed) {
execute handler = e;

if (handler != null) {
handler();
}
}
}

Pete
Jan 2 '08 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: fooooo | last post by:
This is a network app, written in wxPython and the socket module. This is what I want to happen: GUI app starts. User clicks a button to 'start' the work of the app. When start is pressed, a new...
1
by: scott ocamb | last post by:
hello I have implemented a solution using async methods. There is one async method that can be invoked multiple times, ie there are multiple async "threads" running at a time. When these...
4
by: Jesse Elve | last post by:
I am using an XmlValidatingReader which uses an XSD for xml validation. The code has been performing reliably for months. Yesterday it failed for the first time with the following exception: ...
8
by: Robert Zurer | last post by:
I have a server application that makes a MarshalByReferenceObject available via remoting. It's lifetime is set to never expire and it is implemented as a Singleton. Are calls to this object...
6
by: Dan | last post by:
I've created a pocketpc app which has a startup form containing a listview. The form creates an object which in turn creates a System.Threading.Timer. It keeps track of the Timer state using a...
1
by: Gregory Gadow | last post by:
I am looking for a networkwide messaging system to announce server reboots, etc. To implement various custom features, I would much rather roll my own than use an out-of-the-box type of app....
4
by: nhmark64 | last post by:
Hi, Does System.Collections.Generic.Queue not have a Synchronized method because it is already in effect synchronized, or is the Synchronized functionality missing from...
15
by: Laser Lu | last post by:
I was often noted by Thread Safety declarations when I was reading .NET Framework Class Library documents in MSDN. The declaration is usually described as 'Any public static (Shared in Visual...
1
by: raghudr | last post by:
Hi all, I am displaying a splash screen for which i have created a thread. Logic is: 1) i will first create a thread to display a splash screen until a big process is completed 2)then i...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.