I would like to share certain best practices - in order to improve the performance or overcome performance related issues associated with event sink and Programming guidelines for event sinks before you develop for your reference.

  • Exchange store events do not by themselves generate Windows Event Log entries. The underlying ExOLEDB provider generates performance counters for each event sink. The code that executes in response to an Exchange store event code can also generate Windows Event Log events and information for Windows Performance Counters.
  • Exchange store events that can be misused, or that can cause problems if installed incorrectly, should implement the ICreateRegistration interface, and programmatically prevent the event sink from being improperly registered. Cross-store access from within an event sink is not possible. Once registered and wrapped as COM+ applications, any user who knows the name of the event sink can register it in a folder to which they have write permissions.
  • If you have to register an event sink for all mailboxes in a store, you should register the event sink for store-wide events.
  • When Exchange starts up, it looks for and loads all registered event sinks, which takes some time.
  • Using many individual event sink registrations instead of a single store-wide event registration item significantly increases server startup time.
  • Always use care when running store event sinks, especially when using synchronous event sinks.
  • A synchronous event sink is triggered after a data request to the Exchange store but before the item is committed to the store.
  • The synchronous event sink has exclusive control over the item while it is processing. Therefore, a complex or poorly written sink can lock a resource for some time, or even bring an Exchange server to its knees.
  • But, I would recommend you to go through the Programming guidelines for event sinks before you develop:

    • For optimal performance, create an in-process Component Object Model (COM) class that supports execution in a multi-threaded apartment (MTA). The event dispatcher threads execute from within the Microsoft Internet Information Services (IIS) MTA. If your sink supports the single-threaded apartment (STA) only, then all interfaces will be marshaled across the MTA apartment and STA apartment boundaries.
    • Provide an implementation of the IEventIsCacheable interface by your sink. If you implement the IEventIsCacheable interface and the IsCacheable method returns S_OK, the event dispatcher will cache the sink and will use the same object for subsequent events; otherwise, each event will create a new instance of the sink.
    • Never install an untested sink on a production server, especially a sink that runs in- process. Exceptions thrown from within these in-process sinks may disable the IIS (inetinfo.exe) process or cause it to stop responding.
    • Do not place Microsoft Collaboration Data Objects (CDO) interface definitions in your sink’s interface definition language (IDL) file (if you use one directly) when working in C or C++. Information about CDO types—including all classes, interfaces, enumerations, and modules—can be found in the supplied headers. If you do place IDL information in your IDL file, and any of these types are referenced from within your library statement, you will re-map various Interface IDs (IIDs) from the CDO dynamically link library (DLL) to your DLL. This will not cause immediate harm because your DLL contains the necessary type library information required for the universal marshaller to function properly; however, if you subsequently remove the sink from the registry, the CDO libraries will function improperly.

Happy programming !!