Threads, delegates and invoke function with 2.0

M

Melina

Hi,

How can i invoke a function in a mutli-threading environment with .NET 2.0 ?
For example, assuming each thread (in a thread polling application...) needs
to invoke the writeLog function from his createDocument function:

private void createDocument() {
writeLog("Test");
}

private void writeLog(string data) {
StreamWriter sw = new StreamWriter(@"c:\temp\test.txt", true);
sw.WriteLine(data);
sw.Flush();
sw.Close();
}

This code won't run properly because of simultaneous access to writeLog from
the different threads.
I know i can add a Lock into the writeLog function, but i would prefer
invoke delegates.
On a UI control like a TextBox, i can call the Invoke function with the
delegate. But how to do this with a function ?

Many thanks for helping.

Melina.
 
M

Mike Lovell

How can i invoke a function in a mutli-threading environment with .NET 2.0
?
For example, assuming each thread (in a thread polling application...)
needs to invoke the writeLog function from his createDocument function:

private void createDocument() {
writeLog("Test");
}

private void writeLog(string data) {
StreamWriter sw = new StreamWriter(@"c:\temp\test.txt", true);
sw.WriteLine(data);
sw.Flush();
sw.Close();
}

This code won't run properly because of simultaneous access to writeLog
from the different threads.
I know i can add a Lock into the writeLog function, but i would prefer
invoke delegates.
On a UI control like a TextBox, i can call the Invoke function with the
delegate. But how to do this with a function ?

Why would you prefer not to use locks? I mean that's really what locks are
for

If the purpose of this is really logging (as the name suggests) you should
really be using the inbuilt Trace and Debug function for this, then you can
just add a listening and write the debug to a text file.
 
M

Melina

Thanks for answering !

Let me explain the way I see the problem. I may be wrong about the locks...

Well, let's say I have for example 4 threads running simultaneously.
When one of these 4 threads locks the writeLog function, the 3 others have
to wait. In my opinion it's a waste of time !

And I thought that if I use delegates, each thread will be able to call
simultaneously the writeLog function.

Am I wrong ?
 
M

Mike Lovell

Melina said:
Thanks for answering !

Let me explain the way I see the problem. I may be wrong about the
locks...

Well, let's say I have for example 4 threads running simultaneously.
When one of these 4 threads locks the writeLog function, the 3 others have
to wait. In my opinion it's a waste of time !

And I thought that if I use delegates, each thread will be able to call
simultaneously the writeLog function.

Am I wrong ?

Well you're right that they would be waiting. But we're talking about
fractions of a second here.

As far as I know, you don't really have a choice but to waste that time.
The object you're trying to use is a single object, so you cannot use this
object (and remain thread safe) without locking it. If you make multiple
objects of the same type (for logging) in say a delegate, then they would
indeed be independent from each other (from the objects point of view) and
this would work for certain types of object - But seeing as you can only
write to a file from a single thread (because they file would be locked),
you can't really do this when working with files. If you're using the debug
and trace, they are going to take care of all that for you (as they are
internally designed to be thread safe).

If you were say working with SQL, then yes, you could fire off lots of
connections at once if you though it necessary (of course you'd have to
setup your code and/or SQL to handle possible collisions but it would work
better).

Seeing as it's a file, that you have locked open for writing by your object,
using "lock" on the object is going to be necessary I'm afraid. But like I
say, the time loss for this would be tiny.
 
A

Alberto Poblacion

Melina said:
Let me explain the way I see the problem. I may be wrong about the
locks...

Well, let's say I have for example 4 threads running simultaneously.
When one of these 4 threads locks the writeLog function, the 3 others have
to wait. In my opinion it's a waste of time !

And I thought that if I use delegates, each thread will be able to call
simultaneously the writeLog function.

No, the delegates are still running in a thread and still have the same
problem. When you use Invoke on a UI control, you are only using the
delegate to enqueue the call to the function, until *another* thread (the
one that created the UI) becomes available for running your method.
If you want to do a similar operation for your writeLog function, you can
create the queue yourself. Use a Queue class to keep track of all the
pending invocations to writeLog. Then use an additional thread to read from
the queue and invoke writeLog. Of course you will still need a little bit of
locking (during the extremely brief time that is needed to write an item
into the queue or read an item from the queue), but this should be so short
that it would hardly slow down your worker threads.
 
M

Melina

Ok, that's perfectly clear. Thanks to both of you !
I guess that it's the same to write into a Sql database via SqlClient ? I
have to lock the function that writes into the table (in fact that calls a
stored proc to write) ?

Thanks again.

Melina.
 
M

Mike Lovell

Melina said:
Ok, that's perfectly clear. Thanks to both of you !
I guess that it's the same to write into a Sql database via SqlClient ? I
have to lock the function that writes into the table (in fact that calls a
stored proc to write) ?

You always want to lock a shared object you're using.

However some classes might support asynchronous operations, in which case
you're only locking for the time it takes to kick off that operation. But
you'd still lock.

If you're writing, SQL will be able to handle multiple SqlClient objects
talking to the same table (like I said, as long as you have your conflict
resolution and committing worked out) - You won't be able to do that with
the filesystem though, once you're writing to a file you have it locked in
the OS. You wouldn't be able to use multiple objects to write to it (like
you could in SQL).
 
A

Arne Vajhøj

How can i invoke a function in a mutli-threading environment with .NET 2.0 ?
For example, assuming each thread (in a thread polling application...) needs
to invoke the writeLog function from his createDocument function:

private void createDocument() {
writeLog("Test");
}

private void writeLog(string data) {
StreamWriter sw = new StreamWriter(@"c:\temp\test.txt", true);
sw.WriteLine(data);
sw.Flush();
sw.Close();
}

This code won't run properly because of simultaneous access to writeLog from
the different threads.
I know i can add a Lock into the writeLog function, but i would prefer
invoke delegates.

You should use a log.

Or even better: use an existing logging framework like log4net.

Arne

PS: Opening and closing the file all the time will cost
1000 times more than the lock !
 

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