Your discussion intrigued me and I decided to test it eventually :)
I wrote 4 event receivers - ReceiverS1
, ReceiverS2
, ReceiverA1
, ReceiverA2
, sync (seq num 100), sync (seq num 101), async (seq num 100), async (seq num 101) accordingly. I added receivers and verified using sharepoint manager that all settings correct. This is code for receivers:
public class ReceiverS1 : SPItemEventReceiver
{
public override void ItemAdding(SPItemEventProperties properties)
{
properties.AfterProperties["event_x0020_test"] = "ReceiverS1 started: " + DateTime.Now.ToLongTimeString() + "<br>";
//properties.AfterProperties["event_x0020_test"] = (string)properties.AfterProperties["event_x0020_test"] + "Throwing in sync ItemAdding: ReceiverS1 " + "<br>";
//throw new Exception("something wrong happened");
}
}
public class ReceiverS2 : SPItemEventReceiver
{
public override void ItemAdding(SPItemEventProperties properties)
{
if (properties.AfterProperties["event_x0020_test"] != null)
{
var text = (string)properties.AfterProperties["event_x0020_test"];
properties.AfterProperties["event_x0020_test"] = text + " ReceiverS2 started: " + DateTime.Now.ToLongTimeString() + "<br>";
}
}
}
public class ReceiverA1 : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
if (properties.ListItem["event test"] != null)
{
var text = (string) properties.ListItem["event test"];
properties.ListItem["event test"] = text + " ReceiverA1 started: " + DateTime.Now.ToLongTimeString() +"<br>";
//properties.ListItem["event test"] = (string)properties.ListItem["event test"] + "Throwing in async ItemAdded: ReceiverA1 " + "<br>";
properties.ListItem.Update();
Thread.Sleep(10000);
//throw new Exception("something wrong happened");
}
}
}
public class ReceiverA2 : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
if (properties.ListItem["event test"] != null)
{
var text = (string) properties.ListItem["event test"];
properties.ListItem["event test"] = text + " ReceiverA2 started: " + DateTime.Now.ToLongTimeString() +"<br>";
properties.ListItem.Update();
}
}
}
event_x0020_test
is a rich field in some list.
Here is a result from the first test:
ReceiverS1 started: 7:40:29 PM
ReceiverS2 started: 7:40:29 PM
ReceiverA1 started: 7:40:29 PM
ReceiverA2 started: 7:40:39 PM
As you can see from time stamp, A2 (async, 101) receiver started work only when A1 ended (10sec diff). I assume "asynchronous" means that all this async receivers run in one, but separate thread (not one thread for every async receiver).
Next exception test - I uncommented all lines and replace .dll and here is the result:
ReceiverS1 started: 7:42:12 PM
Throwing in sync ItemAdding: ReceiverS1
ReceiverS2 started: 7:42:12 PM
ReceiverA1 started: 7:42:12 PM
Throwing in async ItemAdded: ReceiverA1
ReceiverA2 started: 7:42:22 PM
Even in some of receivers there is an error, all other work as expected, I suppose this is a good and correct behavior.
Hope this helps :)
EDIT
msdn is saying that for every async after-receiver there is a separate thread, I added Thread Id to output test it:
properties.ListItem["event test"] = text + " ReceiverA1 started: " + DateTime.Now.ToLongTimeString() + " Thread ID:" + Thread.CurrentThread.ManagedThreadId.ToString() + "<br>";
And here is the result:
ReceiverS1 started: 10:15:10 AM Thread ID:13
ReceiverS2 started: 10:15:10 AM Thread ID:13
ReceiverA1 started: 10:15:11 AM Thread ID:5
ReceiverA2 started: 10:15:21 AM Thread ID:5
ReceiverA1
and ReceiverA2
both async (I double-checked it using sp manager). It seems that information on msdn is not correct.