3

我正在实施SQLdepenency的过程中我想知道在依赖处理程序执行的情况下它会与主进程产生不同的线程吗?当事件处理程序触发时会发生什么?我需要担心任何多线程问题吗?

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

4 回答 4

2

它在一个单独的线程中工作,但所有通知只有一个这样的线程。查看本文中的 SQLDependency 部分

于 2010-12-14T09:44:56.873 回答
0

它将产生一个新的工作线程来等待依赖项通知——但这就是你想要的(否则你的主程序循环将等待可能永远不会发生的事情!)。

本页的示例代码展示了如何避免获取依赖/查询通知的工作线程无权更新 UI 的问题;他们的方法将任务传递给 UI 线程,因此它会成功(参见步骤 #12)。

于 2010-04-28T19:46:00.563 回答
0

MSDN 上的SqlDependency文档提到了 OnChange 事件可能在与启动命令执行的线程不同的线程上生成的可能性。

您应该阅读MSDN 中的Detecting Changes with SqlDependency (ADO.NET)文章,其中解释了类似的情况。

于 2010-04-28T15:30:51.130 回答
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);
            }
        }
    }
}
于 2010-11-05T17:28:33.607 回答