By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,894 Members | 1,937 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,894 IT Pros & Developers. It's quick & easy.

using lock

P: n/a
Hello,

Why doesn't the lock in Class2::Execute protect the critical section:

public Class1
{
...
public DataTable SchemaTable = new DataTable();
}

Class1 creates many instances of Class2 and calls the corresponding
Execute function on different threads.

public Class2
{
...
public void Execute()
{

// sync multiple threads - ensure only one thread obtains the
schema table
// does not really work, many threads enter this section at the
same time.
lock (_parent.SchemaTable)
{
if (0 == _parent.SchemaTable.Count)
{
_parent.SchemaTable = rdr.GetSchemaTable(); // returns a new
DataTable
}
}
...
}
...
}

I think the problem is that rdr.GetSchemaTable returns a new DataTable
that _parent.SchemaTable points at but I am not really clear how the
..NET internals work. I am able to get around this problem by using a
dedicated SyncLock object.

I would appreciate if someone could point out clearly why the code
should not be expected to work.

Thanks

Nov 17 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
marfind,

Yeah, this is definitely not good. A lock statement basically compiles
to the following:

// If you use lock (this) ;
Montior.Enter(this);

try
{
}
finally
{
Monitor.Exit(this);
}

So, by changing the contents of the reference that was passed to enter,
you never actually release the lock. In effect, you are allocating all of
these locks, which are never released, but every time you make a call, you
change the value of what is locked on the next call. That's why it never
works.

I'm surprized the compiler didn't catch this (it could be because you
are locking on something that is returned from the object).

In the end, you are on the right track, using a dedicated sync lock
object for the lock.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"marvind" <ma********@yahoo.com> wrote in message
news:11*********************@o13g2000cwo.googlegro ups.com...
Hello,

Why doesn't the lock in Class2::Execute protect the critical section:

public Class1
{
...
public DataTable SchemaTable = new DataTable();
}

Class1 creates many instances of Class2 and calls the corresponding
Execute function on different threads.

public Class2
{
...
public void Execute()
{

// sync multiple threads - ensure only one thread obtains the
schema table
// does not really work, many threads enter this section at the
same time.
lock (_parent.SchemaTable)
{
if (0 == _parent.SchemaTable.Count)
{
_parent.SchemaTable = rdr.GetSchemaTable(); // returns a new
DataTable
}
}
...
}
...
}

I think the problem is that rdr.GetSchemaTable returns a new DataTable
that _parent.SchemaTable points at but I am not really clear how the
.NET internals work. I am able to get around this problem by using a
dedicated SyncLock object.

I would appreciate if someone could point out clearly why the code
should not be expected to work.

Thanks

Nov 17 '05 #2

P: n/a
yes, it does help. Thank you.

Nov 17 '05 #3

P: n/a
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
Yeah, this is definitely not good. A lock statement basically compiles
to the following:

// If you use lock (this) ;
Montior.Enter(this);

try
{
}
finally
{
Monitor.Exit(this);
}

So, by changing the contents of the reference that was passed to enter,
you never actually release the lock.


No, that's not true.

According to the spec:

<quote>
A lock statement of the form

lock (x) ...

where x is an expression of a reference-type, is precisely equivalent
to

System.Threading.Monitor.Enter(x);
try {
...
}
finally {
System.Threading.Monitor.Exit(x);
}

except that x is only evaluated once.
</quote>

Note the "x is only evaluated once" bit.

The lock is correctly released, but it won't be the same lock that is
acquired by the next call.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.