Поток SQLDependency - PullRequest
       18

Поток SQLDependency

3 голосов
/ 28 апреля 2010

Я нахожусь в процессе реализации SQL-зависимости, которую я хотел бы знать, в случае выполнения обработчика зависимостей будет ли он отличаться от основного процесса? Что произойдет, когда обработчик событий сработает? Нужно ли беспокоиться о проблемах с многопоточностью?

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 ]

2 голосов
/ 14 декабря 2010

Работает в отдельном потоке, но для всех уведомлений существует только один такой поток.Взгляните на раздел SQLDependency в этой статье

0 голосов
/ 28 апреля 2010

Он создаст новый рабочий поток для ожидания уведомлений о зависимостях - но это то, что вы хотите (в противном случае ваш основной цикл программы будет задерживаться в ожидании чего-то, что может никогда не произойти!)

Пример кода на этой странице показывает, как избежать проблем, когда рабочий поток, который получает уведомления о зависимостях / запросах, не имеет права обновлять пользовательский интерфейс; их метод передает задачу в поток пользовательского интерфейса, поэтому она будет выполнена успешно (см. шаг # 12).

0 голосов
/ 05 ноября 2010

Он появляется в другой ветке !!Вы можете создать простое приложение для Windows, чтобы проверить это, и вы увидите, как обработчик OnChange не может напрямую изменять какие-либо элементы управления пользовательского интерфейса (вы получите что-то вроде «Межпотоковая операция недопустима: доступ к элементу управления XXX из другого потока»).чем нить, на которой он был создан ").Чтобы преодолеть это, вы вызываете BeginInvoke.

Вот простое приложение для Windows для проверки SqlDependencies (надеюсь, вы можете представить себе пользовательский интерфейс).

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);
            }
        }
    }
}
0 голосов
/ 28 апреля 2010

SqlDependency В документации по MSDN упоминается возможность того, что событие OnChange может быть сгенерировано в потоке, отличном от потока, инициировавшего выполнение команды.

Вы должны прочитать Обнаружение изменений с помощью SqlDependency (ADO.NET) статья из MSDN, в которой объясняется похожий сценарий.

...