"Global" thread-safty in sharepoint / WS 3.0

A

Anders J

Hi

We have some code that runs in a EventReceiver ItemAdded handler. The code
must be thread-safe since it is iterating a List to find the max number of a
column and assigns it + 1 to the Item that was added. If it was not
thread-safe, two items could get the same number (which must be unique).

So how do we garantee this in the event handler? Is locking on "this"
enough? I guess not since other types of Event Handlers could as well change
the number. So maybe we need a lock on the whole AppDomain. But how?

public override void ItemAdded(SPItemEventProperties properties)
{
lock(this)
{
// Do thread-safe code here
}
}

(Performance is no issue)

Regards
Anders
 
N

Nicholas Paldino [.NET/C# MVP]

Anders,

If the object is held as a field on your object, then locking on this
would work. However, you should have a separate object that is private that
you use specifically for locking. For example:

// The list.
private List<int> myList = ...;

// The lock on the list.
private readonly object myListLock = new object();

And you might want to encapsulate the operations on a list in separate
methods so that you don't miss locking the list at the appropriate time.

If the list is static, then the same thing applies, it's just that you
should make the field static (and not public, rather, expose your operations
through methods, and have the methods on the type access the private lock
object).

Hope this helps.
 
A

Anders J

Thank Nicholas,

Thanks for your suggestion. But i´m not convinced that i solves my problem.

Lets say i have this. Two users of a list in sharepoint do a action at the
exactly same time. The one Adds a teim an rasies the ItemAddedEventReceiver
and the other updates a item and rasises the ItemUpdatedEventReceiver. Both
these classes iterates through a Sharepoint list to find the highest number
available and increment that with 1 and assigns it to a column. This is true
both in the added an updated evenets.

The look up is done from two completly seperate objects from diffrent
clases. The lookup is in done in a database (Sharepoints through its API).

My concern is that locking on a local object in one of these event handlers
don´t affect the other. I some how need a AppPool wise "thing" to lock on so
that all objects of all classes will lock accordingly to this.

Example code below shows my concern. These locks can effect each other (i
think) but they MUST
--------------
public ItemAddedEventreceiver : SPEventReciver
{
private readonly object myLock = new object();
public override void ItemAdded(SPItemEventProperties properties)
{
lock(myLock)
{
// Get max key in list, incremt with 1 and assign to current item.
}
}
}

public ItemUpdatedEventreceiver : SPEventReciver
{
private readonly object myLock = new object();
public override void ItemUpdated(SPItemEventProperties properties)
{
lock(myLock)
{
// Get max key in list, incremt with 1 and assign to current item.
}
}
}

Regards
Anders

If the object is held as a field on your object, then locking on this
would work. However, you should have a separate object that is private
that you use specifically for locking. For example:

// The list.
private List<int> myList = ...;

// The lock on the list.
private readonly object myListLock = new object();

And you might want to encapsulate the operations on a list in separate
methods so that you don't miss locking the list at the appropriate time.

If the list is static, then the same thing applies, it's just that you
should make the field static (and not public, rather, expose your
operations through methods, and have the methods on the type access the
private lock object).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Anders J said:
Hi

We have some code that runs in a EventReceiver ItemAdded handler. The
code must be thread-safe since it is iterating a List to find the max
number of a column and assigns it + 1 to the Item that was added. If it
was not thread-safe, two items could get the same number (which must be
unique).

So how do we garantee this in the event handler? Is locking on "this"
enough? I guess not since other types of Event Handlers could as well
change the number. So maybe we need a lock on the whole AppDomain. But
how?

public override void ItemAdded(SPItemEventProperties properties)
{
lock(this)
{
// Do thread-safe code here
}
}

(Performance is no issue)

Regards
Anders
 
N

Nicholas Paldino [.NET/C# MVP]

Yes, which is why I suggested "static". If you are running in different
application domains (I don't know what you meant by app pool), then you are
going to have to use some sort of external resource to manage this (a
database, a file) and use the inherent characteristics of that store to
manage concurrency.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Anders J said:
Thank Nicholas,

Thanks for your suggestion. But i´m not convinced that i solves my
problem.

Lets say i have this. Two users of a list in sharepoint do a action at the
exactly same time. The one Adds a teim an rasies the
ItemAddedEventReceiver and the other updates a item and rasises the
ItemUpdatedEventReceiver. Both these classes iterates through a Sharepoint
list to find the highest number available and increment that with 1 and
assigns it to a column. This is true both in the added an updated evenets.

The look up is done from two completly seperate objects from diffrent
clases. The lookup is in done in a database (Sharepoints through its API).

My concern is that locking on a local object in one of these event
handlers don´t affect the other. I some how need a AppPool wise "thing" to
lock on so that all objects of all classes will lock accordingly to this.

Example code below shows my concern. These locks can effect each other (i
think) but they MUST
--------------
public ItemAddedEventreceiver : SPEventReciver
{
private readonly object myLock = new object();
public override void ItemAdded(SPItemEventProperties properties)
{
lock(myLock)
{
// Get max key in list, incremt with 1 and assign to current item.
}
}
}

public ItemUpdatedEventreceiver : SPEventReciver
{
private readonly object myLock = new object();
public override void ItemUpdated(SPItemEventProperties properties)
{
lock(myLock)
{
// Get max key in list, incremt with 1 and assign to current item.
}
}
}

Regards
Anders

If the object is held as a field on your object, then locking on this
would work. However, you should have a separate object that is private
that you use specifically for locking. For example:

// The list.
private List<int> myList = ...;

// The lock on the list.
private readonly object myListLock = new object();

And you might want to encapsulate the operations on a list in separate
methods so that you don't miss locking the list at the appropriate time.

If the list is static, then the same thing applies, it's just that you
should make the field static (and not public, rather, expose your
operations through methods, and have the methods on the type access the
private lock object).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Anders J said:
Hi

We have some code that runs in a EventReceiver ItemAdded handler. The
code must be thread-safe since it is iterating a List to find the max
number of a column and assigns it + 1 to the Item that was added. If it
was not thread-safe, two items could get the same number (which must be
unique).

So how do we garantee this in the event handler? Is locking on "this"
enough? I guess not since other types of Event Handlers could as well
change the number. So maybe we need a lock on the whole AppDomain. But
how?

public override void ItemAdded(SPItemEventProperties properties)
{
lock(this)
{
// Do thread-safe code here
}
}

(Performance is no issue)

Regards
Anders
 
M

Mike Walsh

again (to Anders J) .general is not a newsgroup for duplicates of posts that
are not about general sharepoint questions.

Follow-up amended accordingly.



--
Mike Walsh
WSS FAQ http://www.wssfaq.com
No private e-mail please.
Nicholas Paldino said:
Yes, which is why I suggested "static". If you are running in
different application domains (I don't know what you meant by app pool),
then you are going to have to use some sort of external resource to manage
this (a database, a file) and use the inherent characteristics of that
store to manage concurrency.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Anders J said:
Thank Nicholas,

Thanks for your suggestion. But i´m not convinced that i solves my
problem.

Lets say i have this. Two users of a list in sharepoint do a action at
the exactly same time. The one Adds a teim an rasies the
ItemAddedEventReceiver and the other updates a item and rasises the
ItemUpdatedEventReceiver. Both these classes iterates through a
Sharepoint list to find the highest number available and increment that
with 1 and assigns it to a column. This is true both in the added an
updated evenets.

The look up is done from two completly seperate objects from diffrent
clases. The lookup is in done in a database (Sharepoints through its
API).

My concern is that locking on a local object in one of these event
handlers don´t affect the other. I some how need a AppPool wise "thing"
to lock on so that all objects of all classes will lock accordingly to
this.

Example code below shows my concern. These locks can effect each other (i
think) but they MUST
--------------
public ItemAddedEventreceiver : SPEventReciver
{
private readonly object myLock = new object();
public override void ItemAdded(SPItemEventProperties properties)
{
lock(myLock)
{
// Get max key in list, incremt with 1 and assign to current item.
}
}
}

public ItemUpdatedEventreceiver : SPEventReciver
{
private readonly object myLock = new object();
public override void ItemUpdated(SPItemEventProperties properties)
{
lock(myLock)
{
// Get max key in list, incremt with 1 and assign to current item.
}
}
}

Regards
Anders

If the object is held as a field on your object, then locking on this
would work. However, you should have a separate object that is private
that you use specifically for locking. For example:

// The list.
private List<int> myList = ...;

// The lock on the list.
private readonly object myListLock = new object();

And you might want to encapsulate the operations on a list in
separate methods so that you don't miss locking the list at the
appropriate time.

If the list is static, then the same thing applies, it's just that
you should make the field static (and not public, rather, expose your
operations through methods, and have the methods on the type access the
private lock object).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hi

We have some code that runs in a EventReceiver ItemAdded handler. The
code must be thread-safe since it is iterating a List to find the max
number of a column and assigns it + 1 to the Item that was added. If it
was not thread-safe, two items could get the same number (which must be
unique).

So how do we garantee this in the event handler? Is locking on "this"
enough? I guess not since other types of Event Handlers could as well
change the number. So maybe we need a lock on the whole AppDomain. But
how?

public override void ItemAdded(SPItemEventProperties properties)
{
lock(this)
{
// Do thread-safe code here
}
}

(Performance is no issue)

Regards
Anders
 
M

Mike Walsh

(Sorry about that)

Now follow-ups *are* redirected away from sharepoint.general


Mike Walsh

Mike Walsh said:
again (to Anders J) .general is not a newsgroup for duplicates of posts
that are not about general sharepoint questions.

Follow-up amended accordingly.



--
Mike Walsh
WSS FAQ http://www.wssfaq.com
No private e-mail please.
Nicholas Paldino said:
Yes, which is why I suggested "static". If you are running in
different application domains (I don't know what you meant by app pool),
then you are going to have to use some sort of external resource to
manage this (a database, a file) and use the inherent characteristics of
that store to manage concurrency.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Anders J said:
Thank Nicholas,

Thanks for your suggestion. But i´m not convinced that i solves my
problem.

Lets say i have this. Two users of a list in sharepoint do a action at
the exactly same time. The one Adds a teim an rasies the
ItemAddedEventReceiver and the other updates a item and rasises the
ItemUpdatedEventReceiver. Both these classes iterates through a
Sharepoint list to find the highest number available and increment that
with 1 and assigns it to a column. This is true both in the added an
updated evenets.

The look up is done from two completly seperate objects from diffrent
clases. The lookup is in done in a database (Sharepoints through its
API).

My concern is that locking on a local object in one of these event
handlers don´t affect the other. I some how need a AppPool wise "thing"
to lock on so that all objects of all classes will lock accordingly to
this.

Example code below shows my concern. These locks can effect each other
(i think) but they MUST
--------------
public ItemAddedEventreceiver : SPEventReciver
{
private readonly object myLock = new object();
public override void ItemAdded(SPItemEventProperties properties)
{
lock(myLock)
{
// Get max key in list, incremt with 1 and assign to current item.
}
}
}

public ItemUpdatedEventreceiver : SPEventReciver
{
private readonly object myLock = new object();
public override void ItemUpdated(SPItemEventProperties properties)
{
lock(myLock)
{
// Get max key in list, incremt with 1 and assign to current item.
}
}
}

Regards
Anders


If the object is held as a field on your object, then locking on
this would work. However, you should have a separate object that is
private that you use specifically for locking. For example:

// The list.
private List<int> myList = ...;

// The lock on the list.
private readonly object myListLock = new object();

And you might want to encapsulate the operations on a list in
separate methods so that you don't miss locking the list at the
appropriate time.

If the list is static, then the same thing applies, it's just that
you should make the field static (and not public, rather, expose your
operations through methods, and have the methods on the type access the
private lock object).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hi

We have some code that runs in a EventReceiver ItemAdded handler. The
code must be thread-safe since it is iterating a List to find the max
number of a column and assigns it + 1 to the Item that was added. If
it was not thread-safe, two items could get the same number (which
must be unique).

So how do we garantee this in the event handler? Is locking on "this"
enough? I guess not since other types of Event Handlers could as well
change the number. So maybe we need a lock on the whole AppDomain. But
how?

public override void ItemAdded(SPItemEventProperties properties)
{
lock(this)
{
// Do thread-safe code here
}
}

(Performance is no issue)

Regards
Anders
 
A

Anders J

again (to Anders J) .general is not a newsgroup for duplicates of posts
Sorry about that. Will try post more appropriate next time.

Regards
Anders
 

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