SQL依赖线程

发布于 2024-08-31 00:07:12 字数 1115 浏览 13 评论 0原文

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

i am in the process implementing SQLdepenency i would like to know in case of Dependency Handler exeuctues will it spun a different thred from main Process ? What will happen when the event handler triggers? Do i need to worry about any multithreds issues?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

街道布景 2024-09-07 00:07:12

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

It works in a separate thread, but there is only one such thread for all notifications. Have a look at the SQLDependency section in this article

幻想少年梦 2024-09-07 00:07:12

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

您应该阅读使用 SqlDependency (ADO.NET) 检测更改文章MSDN 解释了类似的情况。

SqlDependency documentation on MSDN mention about possibility that the OnChange event may be generated on a different thread from the thread that initiated command execution.

You should read Detecting Changes with SqlDependency (ADO.NET) article from MSDN which explain similar scenario.

苏璃陌 2024-09-07 00:07:12

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

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

It will spawn a new worker thread to wait for the dependency notifications--but that's what you want (otherwise your main program loop would be held up waiting for something that may never happen!).

The example code at this page shows to how avoid issues where the worker thread that gets the dependency/query notifications doesn't have the right to update the UI; their method passes the task to the UI thread so it will succeed (see step #12).

_失温 2024-09-07 00:07:12

它确实在不同的线程中生成!您可以创建一个简单的 Windows 应用程序来测试这一点,您将看到 OnChange 处理程序如何无法直接修改任何 UI 控件(您会得到类似“跨线程操作无效:从其他线程访问的控件 XXX”的信息)比创建它的线程“)。为了克服这个问题,您可以调用 BeginInvoke。

这是一个简单的 Windows 应用程序来测试 SqlDependency(我希望你能想象一下 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);
            }
        }
    }
}

It does spawn in a different thread!! You can create a simple Windows Application to test this, and you'll see how the OnChange handler can't modify any UI controls directly (you'd get something like "Cross-thread operation not valid: Control XXX accessed from a thread other than the thread it was created on"). To overcome this, you call BeginInvoke.

Here's a simple Windows application to test SqlDependencies (I hope you can imagine the 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);
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文