SqlDependency OnChange Pas De Tir
C'est la première fois que j'ai jamais besoin d'utiliser un SqlDependency donc je suis en espérant que ses une erreur stupide que j'ai fait.
Le problème, je vais avoir, c'est que le OnChanged événement ne se déclenche pas lors de la table sql changements. Pas d'erreur ou quoi que ce soit simplement il n'a pas le feu.
Voici le code
public class SqlWatcher
{
private const string SqlConnectionString = "Data Source = CN-PC08\\DEV; Initial Catalog=DEP; User = sa; Password=******";
public SqlWatcher()
{
SqlClientPermission perm = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted);
perm.Demand();
SqlCommand cmd = new SqlCommand("SELECT [DataAvaliable], [RowNumber] FROM [dbo].[Trigger]", new SqlConnection(SqlConnectionString));
SqlDependency sqlDependency = new SqlDependency(cmd);
sqlDependency.OnChange += On_SqlBitChanged;
}
private void On_SqlBitChanged(object sender, SqlNotificationEventArgs sqlNotificationEventArgs)
{
SqlDependency dependency = (SqlDependency)sender;
dependency.OnChange -= On_SqlBitChanged;
//Fire the event
if (NewMessage != null)
{
NewMessage(this, new EventArgs());
}
}
public void Start()
{
SqlDependency.Start(SqlConnectionString);
}
public void Stop()
{
SqlDependency.Stop(SqlConnectionString);
}
public event EventHandler NewMessage;
Et dans ma fenêtre principale, j'ai ce
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
try
{
SqlWatcher sqlWatcher = new SqlWatcher();
sqlWatcher.Start();
sqlWatcher.NewMessage += On_NewMessage;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void On_NewMessage(object sender, EventArgs eventArgs)
{
MessageBox.Show("Message Received");
}
}
De sorte que le comportement attendu est que si je lance la suite de sqlQuery un messageBox sera affiché en disant: "Message Reçu"
INSERT INTO [DEP].[dbo].[Trigger] Values(0,3)
Quelqu'un pourrait-il me donner un indice sur ce qu'il faut vérifier/changer?
Je suis conscient que seul un sous-ensemble de fonctions Sql peut être utilisé dans les dépendances, mais je ne pense pas que je suis en train de faire quelque chose de fantaisie ici.
OriginalL'auteur Nick Williams | 2013-03-22
Vous devez vous connecter pour publier un commentaire.
Malheureusement (ou heureusement?) vous êtes de faire plusieurs erreurs.
Première est que vous devez comprendre que les Notifications de Requête invalide une requête. Donc vous aurez seulement être notifiée au plus une fois et vous ré-abonner à nouveau (re-soumettre la requête) si vous souhaitez recevoir des notifications.
Ensuite, vous devez comprendre que vous serez notifié pour tout raison, pas seulement pour les changements. Dans votre callback, vous doit vérifier la raison que vous êtes averti, qui sont transmis via le
SqlNotificationEventArgs
.Ensuite, vous devez comprendre la programmation asynchrone principes de base: si vous vous abonnez pour un événement assurez-vous que vous vous abonnez avant l'événement peut se produire la première fois. Affaire au point: le
On_SqlBitChanged
peut tirer dès que vous envoyez la requête. Cette devrait arriver dans leSqlWatcher.SqlWatcher
constructeur, mais vous vous abonnez à lasqlWatcher.NewMessage
après de l'exécution du constructeur.On_SqlBitChanged
peut être invoquée entre le constructeur se termine avant que vous vous accrochez leNewMessage
de rappel d'événement auquel cas l'avis est ignoré en silence.Si vous souhaitez utiliser un service assurez-vous de vous lancer avant vous l'utilisez. Vous utilisez SqlDependency dans
SqlWatcher.SqlWatcher
mais vous le démarrez après que lorsque vous appelezSqlWatcher.Start()
.Enfin, si vous souhaitez être informé des changements sur une requête vous devez soumettre la requête. Vous êtes de la construction de la
SqlCommand
objet, configurer la notification et puis... jeter l'objet. Sauf si vous avez réellement soumettre la requête, vous n'avez pas encore souscrit à rien.Des Suggestions pour les résoudre:
Start
etStop
statique, appelStart
au démarrage de l'application.NewMessage
avant vous soumettre la requêteSqlComamnd.ExecuteQuery()
)Info
,Type
etSource
dans leOn_SqlBitChanged
rappel, si votre présentation contient une erreur c'est la seule façon d'apprendre (le SqlComamnd.ExecuteQuery() va réussir, même si la demande de notification est pas valide)Encore une chose: ne pas invoquer code de l'INTERFACE utilisateur dans le fond des rappels. Vous ne pouvez pas appeler
MessageBox.Show("Message Received");
à partir d'un rappel, vous devez un trajet à travers la forme thread principal viaFormulaire.Invoke
. Oui, je sais que strictement parlant,MessageBox.Show
ne travailler sur un non-thread de l'INTERFACE utilisateur, mais vous allez bientôt déménager à partir de boîtes d'alerte à fait la forme de l'interaction et puis les choses vont se briser.OriginalL'auteur Remus Rusanu