protected virtual void SqlDependency_OnChange(SqlNotificationEventArgs e, Action<IDataRecord, DbOperation> processRecord)
{
Trace.TraceInformation("{0}SQL notification change fired", TracePrefix);
lock (_stopLocker)
{
if (_disposing)
{
return;
}
}
var previousState = Interlocked.CompareExchange(ref _notificationState,
NotificationState.NotificationReceived, NotificationState.ProcessingUpdates);
if (previousState == NotificationState.NotificationReceived)
{
Trace.TraceError("{0}Overlapping SQL change notifications received, this should never happen, BUG!", TracePrefix);
return;
}
if (previousState == NotificationState.ProcessingUpdates)
{
// We're still in the original receive loop
// New updates will be retreived by the original reader thread
Trace.TraceVerbose("{0}Original reader processing is still in progress and will pick up the changes", TracePrefix);
return;
}
// _notificationState wasn't ProcessingUpdates (likely AwaitingNotification)
// Check notification args for issues
if (e.Type == SqlNotificationType.Change)
{
if (e.Info == SqlNotificationInfo.Update)
{
Trace.TraceVerbose("{0}SQL notification details: Type={1}, Source={2}, Info={3}", TracePrefix, e.Type, e.Source, e.Info);
}
else if (e.Source == SqlNotificationSource.Timeout)
{
Trace.TraceVerbose("{0}SQL notification timed out", TracePrefix);
}
else
{
Trace.TraceError("{0}Unexpected SQL notification details: Type={1}, Source={2}, Info={3}", TracePrefix, e.Type, e.Source, e.Info);
Faulted(new SqlMessageBusException(String.Format(CultureInfo.InvariantCulture, Resources.Error_UnexpectedSqlNotificationType, e.Type, e.Source, e.Info)));
}
}
else if (e.Type == SqlNotificationType.Subscribe)
{
Debug.Assert(e.Info != SqlNotificationInfo.Invalid, "Ensure the SQL query meets the requirements for query notifications at http://msdn.microsoft.com/en-US/library/ms181122.aspx");
Trace.TraceError("{0}SQL notification subscription error: Type={1}, Source={2}, Info={3}", TracePrefix, e.Type, e.Source, e.Info);
if (e.Info == SqlNotificationInfo.TemplateLimit)
{
// We've hit a subscription limit, pause for a bit then start again
Thread.Sleep(2000);
}
else
{
// Unknown subscription error, let's stop using query notifications
_notificationState = NotificationState.Disabled;
try
{
SqlDependency.Stop(ConnectionString);
}
catch (Exception) { }
}
}
Changed();
}