SQLDependency线程

时间:2010-04-28 15:19:12

标签: c# events sqldependency

我正在实现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();
}

4 个答案:

答案 0 :(得分:2)

它在一个单独的线程中工作,但所有通知只有一个这样的线程。查看this article

中的SQLDependency部分

答案 1 :(得分:0)

MSDN上的

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);
            }
        }
    }
}