gpt4 book ai didi

c# - ASP.NET 中的 SqlDependency

转载 作者:太空狗 更新时间:2023-10-30 00:59:02 25 4
gpt4 key购买 nike

我在 SQL 依赖对象上创建了以下封装:

public class DependencyTracker
{
private SqlDependency _SQLDependency = null;

public string ConnectionString
{ get; private set; }

public string CommandNotifier
{ get; private set; }

public delegate void Refresh();
public event Refresh OnRefresh;

public DependencyTracker(string connectionString, string commandNotifier)
{
ConnectionString = connectionString;
CommandNotifier = commandNotifier;
}

public void StartDependency()
{
SqlDependency.Start(ConnectionString);
}

public void StopDependency()
{
SqlDependency.Stop(ConnectionString);
}

public void TrackForChanges()
{
using (SqlConnection sqlConn = new SqlConnection(ConnectionString))
{
sqlConn.Open();
using (SqlCommand sqlCommand = new SqlCommand(CommandNotifier, sqlConn))
{
sqlCommand.CommandType = CommandType.StoredProcedure;
_SQLDependency = new SqlDependency(sqlCommand);
_SQLDependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
sqlCommand.ExecuteReader();
}
}
}

void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
SqlDependency sqlDependency = (SqlDependency)sender;
sqlDependency.OnChange -= dependency_OnChange;

if (OnRefresh != null)
{
OnRefresh();
}
}

public bool HasChanges
{
get
{
return _SQLDependency.HasChanges;
}
}
}

这不是原创作品,它基于this text.从我的存储库中,我执行以下操作:

public bool Updatexxx(Ixxx xsxs)
{
try
{
SqlConnection sqlConn = new SqlConnection(_ConnectionString);
sqlConn.Open();
...

bool result = sqlComm.ExecuteNonQuery() == 1;

_ResetEvent.WaitOne();

return result;
}
catch ...
catch ...
}

回调是

public void RefreshData()
{
FindAllxxx();
_ResetEvent.Set();
}

public HashSet<Iddd> Finddadas()
{
DependencyTracker tracker = _Container.Resolve<DependencyTracker>("dada");
UnityHashSet<IT24Route> hash = _Container.Resolve<UnityHashSet<dadas>>("Tdsadas");
if (tracker.HasChanges || hash.Count == 0)
{
hash = new UnityHashSet<dsda>(_Container);
hash.ImportHashSet(FindAlldsdsNonCached());
_Container.RegisterInstance<UnityHashSet<dsds>>("dasda", hash);
tracker.TrackForChanges();
}
return hash;
}

并且 FindAllXXXNonCached() 从数据库中进行真正的选择。如您所见,我正在缓存所有内容。我的问题是为什么这不起作用。症状:从 dependecy tracker 回调被调用两次然后它阻塞。我实现此操作是因为我的通知是在页面刷新开始后发出的。我尝试放置一个手动重置事件以提供通知机会,然后设置手动重置事件并刷新 UI。正如我所说,在通过 OnChange 两次后,它卡住了。我能做什么? Dependency Tracker 是在 Unity 容器中注册的实例,Repository 是类型注册的。

最佳答案

void dependency_OnChange(object sender, SqlNotificationEventArgs e)

您应该检查 SqlNotificationEventArgs 并查看通知您的内容、数据更改或其他内容。检查InfoInsert/Update/Delete .检查SourceData .检查TypeChange .

很可能您的查询会立即发出信号,表明它不符合 restrictions imposed on Query Notifications .是的,我知道该链接指向索引 View ,如果您想了解原因,请阅读 The Mysterious Notification .

您的更新等待 _ResetEvent 和回调信号 _ResetEvent 之间也存在竞争条件。 T1 调用更新。同时,数据中发生不相关的更新并调用回调。 _ResetEvent 已设置。 T1 完成更新并等待 _ResteEvent,它已发出信号,因此它会继续。调用者假设它自己的更新的回调发生并且缓存被刷新,但事实并非如此。

第二个更严重的问题是在存在交易的情况下代码不正确。 UpdateXXX 假定其自身更新的回调将立即发生并等待它。查询通知将仅在更新提交后由引擎传递,因此当存在 TransactionScope 时,UpdateXXX 方法将阻塞等待通知,直到 UpdateXXX 返回(实时死锁)。

也不清楚 TrackForChanges 的目的是什么。您正在读取 SqlDataReader (sqlCommand.ExecuteReader) 但忽略结果。使用查询通知,您可以提交查询,读取其结果,当结果发生变化时您会收到通知。

最后,never read data in the SqlDependency notification callback .

关于c# - ASP.NET 中的 SqlDependency,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1555242/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com