首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

ADO.NET 2.0 中的查詢通知(四):SqlDependency 進階設定與 SqlNotificationRequest 實作

     編輯:關於C語言

SqlDependency 事件處理模式

相同代碼也可用 Visual Basic .NET 撰寫,使用熟悉的 WithEvents 關鍵字與 SqlDependency。注意此程式只接收與處理一個 OnChanged 事件,不管底層資料列集發生多少次改變。收到通知時工作就是重新提交附帶新通知請求的命令,並用命令執行結果重新整理快取以反映新資料。若將前例 Main() 代碼移至具名常式,代碼如下:

static void Main(string[] args)
{
    GetAndProcessData();
    UpdateCache();
    Console.WriteLine("Press Enter to continue");
    Console.ReadLine();
}
static void MyOnChanged(object caller, SqlNotificationEventArgs e)
{
    GetAndProcessData();
    UpdateCache();
}

透過幾小段文字可了解在 ASP.NET 2.0 中採用完全相同方式,使用 ASP.NET Cache 類別作為資料快取。

SqlDependency 通訊機制

SqlDependency 仰賴內建於 SQL Server 2005 的分派器建立與客戶端連接並發送通知訊息。分派器使用 out-of-band 通訊而非 SqlConnection。意味著您的客戶端必須能「透過網路到達」SQL Server;防火牆或網路位址轉換可能妨礙此通訊。未來 Beta 版將允許對埠設定有更多控制權,以更友善通過防火牆限制。可透過指定 SqlDependency 建構函式參數完整設定伺服器與客戶端通訊工作。範例:

SqlDependency depend = new SqlDependency(cmd,
    null,
    SqlNotificationAuthType.None,
    SqlNotificationEncryptionType.None,
    SqlNotificationTransports.Tcp,
    10000);

此建構函式允許選擇不同於預設值的行為。所有可改變行為中最有用的是伺服器用於連接客戶端的傳輸協定。範例使用 SqlNotificationTransports.Tcp,伺服器可用 TCP 或 HTTP。參數預設值為 SqlNotificationTransports.Any;讓伺服器「決定」用哪個協定。若指定 Any,當客戶端作業系統包含核心模式 HTTP 支援時,伺服器將用 HTTP,否則用 TCP。Windows Server 2003 與 Windows XP SP2 均包含核心 HTTP 支援。因訊息透過網路發送,可指定身分驗證類型。目前 EncryptionType 為參數,但未來 Beta 版將移除。目前兩值預設皆為 None。

SqlNotificationAuthType 也支援整合驗證。可顯式指定訂閱逾時值與 SQL Server Service Broker 的 SERVICE 名稱。SERVICE 名稱通常設為空,如範例所示,但也可顯式指定內建 SqlQueryNotificationService 為 SERVICE 名稱。最可能被修改參數是 SqlNotificationTransport 與 timeout。注意這些參數只能套用於 SqlDependency,因參數指定伺服器端分派器行為。使用 SqlNotificationRequest 時不會用到分派器。

使用 SqlNotificationRequest

使用 SqlNotificationRequest 僅在設定方面比 SqlDependency 複雜一點,但主要取決於程式如何處理訊息。用 SqlDependency 時,伺服器通知發送到 MSDB 資料庫的 SqlQueryNotificationService 由它處理通知。用 SqlNotificationRequest 時必須自己處理訊息。這裡有簡單範例,使用 SqlNotificationRequest 與本文前面定義的 SERVICE:

using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;

class Class1
{
    string connstring = null;
    SqlConnection conn = null;
    SqlDataReader rdr = null;

    static void Main(string[] args)
    {
        connstring = GetConnectionStringFromConfig();
        conn = new SqlConnection(connstring);
        Class1 c = new Class1();
        c.DoWork();
    }

    void DoWork()
    {
        conn.Open();
        rdr = GetJobs(2);
        if (rdr != null)
        {
            rdr.Close();
            WaitForChanges();
        }
        conn.Dispose();
    }

    public SqlDataReader GetJobs(int JobId)
    {
        using (SqlCommand cmd = new SqlCommand(
            "Select job_id, job_desc from dbo.jobs where job_id = @id", conn))
        {
            try
            {
                cmd.Parameters.AddWithValue("@id", JobId);
                SqlNotificationRequest not = new SqlNotificationRequest();
                not.Id = new Guid();
                // 這必須是 pubs 資料庫中名為 MyService 的服務
                // 關聯佇列 notificationqueue (見下文)
                // 服務必須遵循 QueryNotifications 契約
                not.Service = "myservice";
                not.Timeout = 0;
                // 掛載通知請求
                cmd.Notification = not;
                rdr = cmd.ExecuteReader();
                while (rdr.Read())
                    Console.WriteLine(rdr[0]);
                rdr.Close();
            }
            catch (Exception ex)
            { Console.WriteLine(ex.Message); }
            return rdr;
        }
    }

    public void WaitForChanges()
    {
        // 等待通知出現在佇列,然後自行讀取
        using (SqlCommand cmd = new SqlCommand(
            "WAITFOR (Receive convert(XML, message_body) from notificationqueue)", conn))
        {
            object o = cmd.ExecuteScalar();
            // 依喜好處理通知訊息
            Console.WriteLine(o);
        }
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved