程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> ADO.NET 2.0中的查詢通知(4)

ADO.NET 2.0中的查詢通知(4)

編輯:關於C語言

同樣的代碼您也可以使用Visual Basic .Net編寫,使用熟悉的WithEvents關鍵字和SqlDependency. 注意這段程序只接收和處理一個OnChanged事件,而不管底層行集發生了多少次改變。收到通知時我們要做的工作就是重新提交附帶新的通知請求的命令,並使用該命令的執行結果刷新緩存以反映出新數據。如果將上面例子中Main() 的代碼轉移到一個命名的例程中,代碼看起來應如下所示:

static void Main(string[] args)
{
GetAndProcessData();
UpdateCache();
// wait for user to end program
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依靠內置在SQL Server 2005中的分發器建立和客戶端的連接以及發送通知消息。分發器使用的是out-of-band通信而不是使用SqlConnection。這也意味著您的客戶端必須可以“通過網絡到達”SQL Server;防火牆或者網絡地址轉換可能會妨礙這種通訊。未來的beta版將允許您對端口配置有更多的控制權,從而可以更友好地通過防火牆的限制。可以通過指定SqlDependency構造方法中的參數來完全配置服務器和客戶端的通信工作。示例如下:

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

SqlDependency的這個構造方法允許您選擇不同於默認值的行為。所有可改變行為中最有用的就是服務器用於連接客戶端所使用的傳輸協議。該例中使用的是SqlNotificationTransports.Tcp,服務器可以使用TCP或者HTTP。該參數的默認值是SqlNotificationTransports.Any;這樣讓服務器來“決定”使用哪個傳輸協議。如果指定Any,那麼當客戶端操作系統中包含了核心模式HTTP支持時,服務器將使用HTTP協議,否則使用TCP。Windows Server 2003和Windows XP with 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();
// this must be a service named MyService in the pubs database
// associated with a queue called notificationqueue (see below)
// service must go by QueryNotifications contract
not.Service = "myservice";
not.Timeout = 0;
// hook up the notification request
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()
{
// wait for notification to appear on the queue
// then read it yourself
using (SqlCommand cmd = new SqlCommand(
"WAITFOR (Receive convert(XML,message_body) from notificationqueue)",  
conn))
{
object o = cmd.ExecuteScalar();
// process the notification message however you like
Console.WriteLine(o);
}
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved