我在最后几天遇到了使用SQL依赖关系的麻烦。
在this link中的示例中,我几乎达到了目标。 "几乎"因为事件被正确触发,而且在启动时,我调用了MyService类的Start方法。这里有我的代码,但你可以看到它的链接是相同的(或差不多的)。
我想我可以简单地插入bool值,只是为了避免初始化事件,但我认为另一种解决方案会更好。
SQLWatcher:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
public enum SqlWatcherNotificationType
{
Blocking,
Threaded // Launch in another thread so SqlWatcher can immediately start monitoring again.
}
public class SqlWatcher : IDisposable
{
private string ConnectionString;
private SqlConnection Connection;
private SqlCommand Command;
private SqlDataAdapter Adapter;
private DataSet Result;
private SqlWatcherNotificationType NotificationType;
public SqlWatcher(string ConnectionString, SqlCommand Command, SqlWatcherNotificationType NotificationType)
{
this.NotificationType = NotificationType;
this.ConnectionString = ConnectionString;
SqlDependency.Start(this.ConnectionString);
this.Connection = new SqlConnection(this.ConnectionString);
this.Connection.Open();
this.Command = Command;
this.Command.Connection = this.Connection;
Adapter = new SqlDataAdapter(this.Command);
}
public void Start()
{
RegisterForChanges();
}
public void Stop()
{
SqlDependency.Stop(this.ConnectionString);
}
public delegate void SqlWatcherEventHandler(DataSet Result);
public event SqlWatcherEventHandler OnChange;
public DataSet DataSet
{
get { return Result; }
}
private void RegisterForChanges()
{
//Remove old dependency object
this.Command.Notification = null;
//Create new dependency object
SqlDependency dep = new SqlDependency(this.Command);
dep.OnChange += new OnChangeEventHandler(Handle_OnChange);
//Save data
Result = new DataSet();
Adapter.Fill(Result);
//Notify client of change to DataSet
switch (NotificationType)
{
case SqlWatcherNotificationType.Blocking:
OnChange(Result);
break;
case SqlWatcherNotificationType.Threaded:
ThreadPool.QueueUserWorkItem(ChangeEventWrapper, Result);
break;
}
}
public void ChangeEventWrapper(object state)
{
DataSet Result = (DataSet)state;
OnChange(Result);
}
private void Handle_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type != SqlNotificationType.Change)
throw new ApplicationException("Failed to create queue notification subscription!");
//Clean up the old notification
SqlDependency dep = (SqlDependency)sender;
dep.OnChange -= Handle_OnChange;
//Register for the new notification
RegisterForChanges();
}
public void Dispose()
{
Stop();
}
}
这是MyService类:
public class MyService
{
private static SqlWatcher SqlQueueWatcher;
public static void Start()
{
string connS = MainWindow.dbContext.Database.Connection.ConnectionString + "Password=111;";
//Build the command object we want to monitor (don't include a SqlConnection)
SqlCommand cmd = new SqlCommand();
cmd = new SqlCommand("SELECT CODVEI FROM dbo.ArchivioErogazioni");
cmd.CommandType = CommandType.Text;
//Setup the SQLWatcher
SqlQueueWatcher = new SqlWatcher(connS, cmd, SqlWatcherNotificationType.Blocking);
SqlQueueWatcher.OnChange += new SqlWatcher.SqlWatcherEventHandler(QueueSQLWatcher_OnChange);
SqlQueueWatcher.Start();
}
private static void QueueSQLWatcher_OnChange(DataSet Result)
{
//Do something with the updated DataSet object
Debug.WriteLine("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); ---> ENTERS HERE IN THE INIT PHASE
}
public static void Stop()
{
SqlQueueWatcher.Dispose();
}
}
这就是我简单地称之为:
MyService.Start();
布尔旗是个坏主意吗?为什么它在启动时进入QueueSQLWatcher_OnChange?
答案 0 :(得分:0)
要解决此问题,您只需将SqlCommand
的通知设置为空。
cmd.Notification = null;
试试这个,我认为你的问题将得到解决。在使用SqlWatcher
类