我正在实现SQLdepenency的过程中我想知道在Dependency Handler exeuctues的情况下它是否会从主进程中转出一个不同的thred?事件处理程序触发时会发生什么?我是否需要担心任何多线程问题?
public void CreateSqlDependency()
{
try
{
using (SqlConnection connection = (SqlConnection)DBFactory.GetDBFactoryConnection(Constants.SQL_PROVIDER_NAME))
{
SqlCommand command = (SqlCommand)DBFactory.GetCommand(Constants.SQL_PROVIDER_NAME);
command.CommandText = watchQuery;
command.CommandType = CommandType.Text;
SqlDependency dependency = new SqlDependency(command);
//Create the callback object
dependency.OnChange += new OnChangeEventHandler(this.QueueChangeNotificationHandler);
SqlDependency.Start(connectionString);
DataTable dataTable = DBFactory.ExecuteSPReDT(command);
}
}
catch (SqlException sqlExp)
{
throw sqlExp;
}
catch (Exception ex)
{
throw ex;
}
}
public void QueueChangeNotificationHandler(object caller, SqlNotificationEventArgs e)
{
if(e.Info == SqlNotificationInfo.Insert)
Fire();
}
答案 0 :(得分:2)
它在一个单独的线程中工作,但所有通知只有一个这样的线程。查看this article
中的SQLDependency部分答案 1 :(得分:0)
SqlDependency文档提到了可能在与启动命令执行的线程不同的线程上生成OnChange事件的可能性。
您应该阅读MSDN中的Detecting Changes with SqlDependency (ADO.NET)文章,该文章解释了类似的情况。
答案 2 :(得分:0)
它将生成一个新的工作线程来等待依赖性通知 - 但这就是你想要的(否则你的主程序循环将被等待可能永远不会发生的事情!)。
this page处的示例代码显示了如何避免获取依赖/查询通知的工作线程无权更新UI的问题;他们的方法将任务传递给UI线程,因此它将成功(参见步骤#12)。
答案 3 :(得分:0)
它确实在不同的线程中产生!!您可以创建一个简单的Windows应用程序来测试它,您将看到OnChange处理程序如何不能直接修改任何UI控件(您会得到类似“跨线程操作无效:控制XXX从其他线程访问”的内容)而不是它在“)上创建的线程。要解决这个问题,请调用BeginInvoke。
这是一个简单的Windows应用程序来测试SqlDependencies(我希望你能想象出UI)。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Linq;
using System.Data.Linq.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace TestSqlDependancies
{
public partial class SqlDependencyTester : Form
{
SqlDependency sqlDepenency = null;
SqlCommand command;
SqlNotificationEventArgs msg;
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
public delegate void InvokeDelegate();
void sqlDepenency_OnChange(object sender, SqlNotificationEventArgs e)
{
msg = e;
this.BeginInvoke(new InvokeDelegate(Notify));
}
private void Notify()
{
listBox1.Items.Add(DateTime.Now.ToString("HH:mm:ss:fff") + " - Notfication received. SqlDependency " + (sqlDepenency.HasChanges ? " has changes." : " reports no change. ") + msg.Type.ToString() + "-" + msg.Info.ToString());
}
private void button1_Click(object sender, EventArgs e)
{
SetDependency();
}
private void SetDependency()
{
try
{
using (TicketDataContext dc = new TicketDataContext())
{
SqlDependency.Start(dc.Connection.ConnectionString);
command = new SqlCommand(textBox1.Text, (SqlConnection)dc.Connection);
sqlDepenency = new SqlDependency(command);
sqlDepenency.OnChange += new OnChangeEventHandler(sqlDepenency_OnChange);
command.Connection.Open();
command.ExecuteReader();
}
}
catch (Exception e)
{
listBox1.Items.Add(DateTime.Now.ToString("HH:mm:ss:fff") + e.Message);
}
}
}
}