Monday, January 7, 2008

CSE 2008: Bill giới thiệu SYNC dành cho Ford Motor

Hum nay CSE 2008 mới khai mạc, anyway, Bill đã "khai hỏa" CSE 2008 bằng bài diễn văn và giới thiệu công nghệ mới khá ấn tượng vào ngày hôm qua.

Tham vọng của Bill là everything đều dựa vào Microsoft. Đợt này, Microsoft cũng giới thiệu một công nghệ mới gọi là SYNC.

http://img141.imageshack.us/img141/903/syncphotora6.jpg

SYNC là một công nghệ của Microsoft trang bị cho dòng xe Ford nhằm nâng cao các tính năng cao cấp cho dòng xe Ford mới dự kiến xuất xưởng vào năm 2009.

Với SYNC, hệ thống sẽ tự động gọi 911 (một số gọi khẩn cấp ở Mỹ) khi phát hiện ra tai nạn xe mà không cần phải chủ xe kích hoạt. Để sử dụng chức năng này này, tài xế chỉ cần 1 cái phone tương thích với SYNC, chức năng call sẽ sử dụng phone line của tài xế.

Sau khi tai nạn xảy ra, hệ thống sẽ tự động đếm ngược trong vòng 10s, trong trường hợp, đó chỉ là những va chạm mà tài xế có thể chủ động xử lý, thì tài xế có thể hủy cuộc gọi trong vòng 10s đó.

http://img141.imageshack.us/img141/9229/911assistoptfc8.jpg
Nếu sau 10s mà tài xế ko hủy cuộc gọi, hệ thống sẽ tự động assume rằng tai nạn xảy ra và người tài xế đã không còn tỉnh tảo hoặc đã bất tỉnh, và hệ thống tự động báo về cho tổng đài 911 vị trí tọa độ của chiếc xe đang bị tai nạn.

Tuy nhiên, về mặt cá nhân, không biết Microsoft và Ford sẽ xử lý ra sao nếu như hệ thống SYNC của Microsoft này bị dính bug (chuyện phần mềm dính bug là chuyện thường), lúc đó chủ xe có thể bị phạt vì quậy phá 911 mà ko hề hay biết.

Một tính năng nữa nổi trội của SYNC với Ford nữa đó là Vehical Health Report. Với tính năng này, SYNC sẽ tự động gởi các bản report về hệ thống chăm sóc khách hàng của Ford và thông báo với chủ xe rằng xe cần được bảo hành, sữa chữa hoặc những hệ thống nào cần kiểm tra. Tất nhiên, là những thông báo này đều được điều chỉnh bởi chủ xe.

Dưới đây là một vài hình ảnh về SYNC tại CSE 2008 do Microsoft giới thiệu hôm qua:

http://img141.imageshack.us/img141/9522/dsc0205ft2.jpg

http://img141.imageshack.us/img141/4121/dsc0228aq5.jpg

http://img141.imageshack.us/img141/3289/dsc0216tq4.jpg


Saturday, November 3, 2007

Những cái mới trong C# .NET 3.0


Một số bạn hỏi tôi rằng có phải C# 3.0 nằm trong .NET 3.0 Framework hay không? Xin thưa là không? Mà C# 3.0 được giới thiệu trong .NET 3.5. [Xem thêm ở đây]

Trong C# 3.0 có một số tính năng mới đã được giới thiệu, dưới đây là liệt kê tóm tắt các tính năng đó:

  • Khai báo biến kiểu không tường minh (Implicitly typed local variables)
  • Tạo kiểu (lớp) tạm thời (Anonymous types)
  • Các phương thức mở rộng (Extension methods)
  • Khởi tạo các Object và Collection (Object and collection initializers)
  • Biểu thức Lambda (Lambda expressions)
  • Biểu thức truy vấn LINQ (Query expressions)
  • Biểu thức cây (Expression Trees)
  • Tự động xây dựng Properties (Auto-Implemented Properties)

Nội dung dưới đây sẽ đi sâu chi tiết vào một số các tính năng mới này.

Implicitly Typed Local Variables

C# 3.0 đưa thêm 1 từ khoá mới gọi là "var". Từ khoá var cho phép định nghĩa 1 biến mà không cần khai báo kiểu tường minh, như ví dụ dưới đây là hợp lệ trong C# 3.0

var i = 1;

Một điểm lưu ý khi sử dụng khai báo này là giá trị gán vào phải được thực hiện ngay sau lệnh khai báo. Khi thực hiện lệnh gán thì biến đã được ngầm định khai báo kiểu tương ứng. Trong ví dụ:

var i = 1; // Correct
var i; //Incorrect

thì dòng lệnh thứ nhất khai báo là hợp lệ, và i được hiểu là kiểu int. Nhưng đối với dòng lệnh thứ 2, thì không được chấp nhận. Ngoài ra, kiểu dữ liệu được gán vào cũng không được là kiểu null.

Nếu ai đã từng sử dụng VB6 thì cũng lưu ý, đây không phải là kiểu Object cũng không phải là kiểu variant.

Đối với khởi tạo các kiểu dữ liệu mảng, thì có thể sử dụng syntax hơi khác một chút như ví dụ:

var intArr = new[] { 1, 2, 3, 4 };// Declare an array

Dòng code trên có thể được hiểu là intArr as int[];

Ngoài ra, var còn dùng để khai báo các biến có kiểu dùng tạm (Anonymous Types) sẽ được làm rõ trong phần kế tiếp.

Anonymous Types

C# 3.0 cho phép tạo ra các class dùng tạm thời mà không cần phải định nghĩa class đó trước. Ví dụ, mình cần 1 class tạm thời dùng để khai báo 1 mẫu xe có các thuộc tính là năm SX (manf), màu sắc (color) và số chỗ ngồi (seats) thì dưới đây là 1 ví dụ cho phép khai báo như vậy:

var mycar = new { manf = 2007, color = System.Drawing.Color.Black, seats = 4 };
mycar.manf = 2006;
mycar.color = System.Drawing.Color.White;

Trong dòng code trên, từ khoá new cho phép định nghĩa ra 3 thuộc tính là manf, color và seats. Khi compile, C# Compiler sẽ tạo ra 1 class tương tự vậy

class __Anonymous1 {

private int _manf = 2007;
private int _seats = 4;
private System.Drawing.Color _color = System.Drawing.Color.Black;
public string manf
{
get { return _manf; }
set { _manf = value; }
}

public string seats
{
get { return _seats; }
set { _seats = value; }
}

public int color
{
get { return _color; }
set { _color = value; }
}

}

Ngoài ra, nếu như có 1 khai báo khác tương tự để tạo 1 instances mới cho 1 class kiêủ như vậy, thì C# Compiler cũng đủ thông minh để tạo ra 1 class cho >2 khai báo như vậy, và thậm chí, trong code, có thể gán giá trị cho nhau (vì chung 1 type)

Extension Methods

Extension Method là 1 tính năng rất hay trong C# 3.0 này.

Giả sử bạn có được 1 class từ đâu đó, tuy nhiên, bạn không có code mà chỉ có file dll mà thôi. Bạn muốn mở rộng và thêm 1 số hàm của class MyPoint chẳng hạn, thì thông thường bạn sẽ làm cách nào? Inherit , viết Wrapper ...?

Với Extension methods, thì C# cho phép lập trình viên viết các method cho các lớp khác một cách khá dễ dàng. Hãy xem ví dụ sau, class MyPoint là 1 class không có sẵn source, và mình muốn thêm 1 hàm để tính Distance giữa 2 điểm (2 object MyPoint) là từ chính MyPoint đang xét tới 1 MyPoint khác.

Rất đơn giản, khai báo 1 class khác và khai báo thêm hàm cần thêm vào, lưu ý từ khoá this trong Parameter đầu tiên

public static class MyExtend{

public static int DistanceTo(this MyPoint mp, MyPoint another){

//Process the method here
return (mp.x + mp.y) - (another.x + another.y);

}

}

Và trong lớp cần sử dụng... (trong ví dụ sau có dùng 1 tính năng mới của C# 3.0 là Object, Collection Initilizers sẽ được bàn sau)

List<MyPoint> allPoints = new List<MyPoint>{

new MyPoint{x = 1, y=2},
new MyPoint{x = 3, y=4},
new MyPoint{x = 4, y=2},
new MyPoint{x = 2, y=5}
};

int result = allPoints[1].DistanceTo(allPoints[2]);

Từ ví dụ trên, có thể thấy hàm DistanceTo được xem như 1 hàm của lớp MyPoint.

Khi sử dụng tính năng này, cần lưu ý:

  1. Hàm cần thêm vào phải là hàm static
  2. Hàm cần thêm vào phải đặt vào trong 1 class static
  3. Kiểu dữ liệu của tham số đầu tiên sẽ tương ứng với kiểu dữ liệu cần thêm vào.
  4. Từ khoá this phải đặt ở tham số đầu tiên
  5. Để sử dụng, thì class dùng để khai báo phải visible trong context cần sử dụng (dùng using...)

Object and Collection Initializers

C# 3.0 cũng cho phép khởi tạo các đối tượng và khai báo chỉ trong cùng 1 câu lệnh, và class cũng không cần phải có các constructor, hãy xem ví dụ khai báo Class MyPoint dưới đây:

public class MyPoint{

int _x = 0;
public int x {

get { return _x; }
set { _x = value; }

}

int _y = 0;
public int y{

get { return _y; }
set { _y = value; }

}

}

Lưu ý là ở đây, Minh không khai báo bất kỳ Constructor nào. Hãy xem ví dụ ở trên về Extension Method, C# 3.0 cho phép viết khởi tạo các class như đã được nêu ở bên trên

Đơn giản hơn:

MyPoint p = new MyPoint() { x = 1, y = 4 };

Cũng đã có câu hỏi rằng tại sao không gọi vậy cho lẹ:

MyPoint p = new MyPoint(1,4);

Do ở đây không sử dụng Constructor, nên cách gọi này là gọi 1 constructor với 2 tham số 1 và 2...

Auto-Implemented Properties

Trong lúc lập trình, việc khai báo các Properties cho 1 class là chuyện làm rất thường xuyên, như ví dụ ở trên, class MyPoint được khai báo các properties như sau

public class MyPoint{

int _x = 0;
public int x {

get { return _x; }
set { _x = value; }

}

int _y = 0;
public int y{

get { return _y; }
set { _y = value; }

}

}

Đa số các Properties đều thực hiện các thao tác như là ghi và đọc từ 1 biến private nào đó. Trong C# 3.0, nếu như properties của bạn chỉ thực hiện các thao tác như ở trên (đọc và ghi vào biến private) thì không cần phải khai báo như vậy, mà thay vào đó chỉ cần khai báo:

public class MyPoint{

public int x {get ; set;}

public int y {get ; set; }

}

Khi biên dịch, thì C# Compiler sẽ tự động tạo ra các biến private tương tự y như khai báo tường minh ở khai báo trên. Kết quả là 2 khai báo hoàn toàn tương tự nhau.


3 tính năng còn lại bữa sau viết tiếp vô đây, hết giờ ... làm rồi

Wednesday, September 19, 2007

.NET Framework 3.0 (part 2)

Trong Entry trước đã có nói về các Foundation của .NET 3.0 trở lên là WPF - Windows Presentation Foundation, WCF - Windows Communication Foundation, WF - Windows Workflow Foundation , Windows CardSpace.

Entry này sẽ đi sâu hơn những khác biệt trong các .NET framework, từ 1.x, 2.0, 3.0 và 3.5 (beta)

Dưới đây là bảng so sánh một cách khái quát giữa các framework và các tính năng.


.NET 1.1

.NET 2.0

.NET 3.0

.NET 3.5

CLR Version

CLR 1.0

CLR 2.0

CLR 2.0

CLR 3.0

C#-version

C# 1.0

C# 2.0

C# 2.0

C# 3.0

Pre-installed on OS

Windows Server 2003

Windows Server 2003 R2

Windows Vista

Windows Server 2008

Foundations

N/A

N/A

WPF
WCF
WF
WCS

WPF
WCF
WF
WCS

ADO

ADO.NET

ADO.NET 2.0

ADO.NET 2.0

ADO.NET vNext= LINQ

Special editions

.NET Compact Framework 1.0 .NET Compact Framework 2.0
  • .NET Compact Framework 2.0
  • .NET Micro Framework 2.0
  • .NET Compact Framework 3.5
  • Silverlight 1.1
  • .NET Micro Framework 2.0

Từ bảng trên, có thể thấy một số điểm sau đây:

  • Từ 1.x lên 2.0 đã có sự thay đổi cơ bản về cấu trúc bên dưới của .NET framework (CLR 1.0 --> CLR 2.0)
  • Từ 2.0 lên 3.0 về cơ bản thì không có gì thay đổi nhiều trừ các Foundation được đưa vào. Như vậy, những ứng dụng đã được viết để chạy trên .NET 2.0 hoàn toàn có thể chạy được trên nền 3.0. Từ đó, nếu bạn đang sử dụng .NET 1.x, và bạn muốn nâng cấp lên, tốt nhất là nâng cấp lên 3.0 luôn mà ko cần phải cài .NET 2.0. Ngay cả trong lập trình C#, thì C# vẫn là 2.0. Do đó, nếu đang cài .NET 2.0, và bạn chưa cần phải sử dụng các Foundation mới, thì việc cài đặt 3.0 là không cần thiết.
    Như vậy, nếu để đưa ra một lời khuyên cho bạn nên cài .NET framework nào, thì .NET 3.0 vẫn được prefer hơn cả vì nó bao gồm cả 2.0 và .NET 3.5 thì chưa được ổn định (beta)
  • .NET 3.0 có chứa 1 compiler mới để xử lý các new features và để xử lý LINQ

Các tính năng mới trong .NET 3.5

Thực thi bên dưới Framework nhanh hơn

  1. Bộ thu dọn "Rác" trong bộ nhớ làm việc nhanh hơn
  2. Quá trình NGen nhanh hơn, "thông minh" hơn đồng thời cũng yêu cầu ít bộ nhớ hơn.
  3. Cải thiện các tính năng hỗ trợ CPU 64 bit
  4. Nâng cao performance cuả ThreadPool
  5. Security check caching trong quá trình thực thi NGen.

Base Class Library – Các class mới

  1. Thêm các kiểu dữ liệu mới: BigInteger, HashSet và DateTime2
  2. NSA Suite ”B” and FIPs compliant cryptography
  3. Lightweight Reader/Writer Lock Classes
  4. Anonymous and Named Pipes IO Classes
  5. Tích hợp với Event Tracing for Windows
  6. New Addin hosting model for extensibility

Language Integrated Query (LINQ)

  1. Đưa LINQ vào ngôn ngữ lập trình (C# và VB .NET) và cả trong framework

Workflow Enabled Services – Process and Messaging together

  1. Sử dụng Workflow để tạo ra các Services có khả năng chạy trong thời gian lâu dài và ổn định. Công cụ mới là WF activities and new programming model classes cũng đã được thêm vào để đơn giản hoá quá trình tạo ra các Service có Workflow được ứng dụng sử dụng WF và WCF. Tính năng này cho phép các lập trình viên có thể phát triển các business logic cho các Service sử dụng WF đồng thời gởi message từ Service đó thông qua WCF, điều này cho phép đưa ra những chiến lược tốt hơn và giảm thời gian viết code so với trước đó.

Web 2.0 Friendly and AJAX Enabled WCF Services

Visual Studio Developer Tools for WF, WCF and in Visual Studio “Orcas”

More WS-* Standards Support

  1. Implementation in WCF of the latest OASIS specifications Web Services Atomic Transaction (WS-AtomicTransaction) 1.1, WS-ReliableMessaging 1.1, WS-SecureCOnversation and Web Services Coordination (WS-Coordination) 1.1.

RSS and ATOM Syndication API

  1. Trong .NET 3.5 hỗ trợ các tính năng có thể sinh ra các RSS và ATOM Syndication một cách dễ dàng hơn.

Partial Trust Support for WCF Hosting

  1. Partial trust on the client is provided for ASMX parity focussing mainly on partially trusted WCF applications deployed through click-once. Support is provided for basic HTTP binding provided that the application runs in the Internet zone permissions and have granted the apropriate WebPermission. Secure communication is possible through transport security only. All other features are not available to partially trusted applications including hosting services, duplex communications, non-HTTP transports, WS-* protocols and any WF use.

Rules Data Improvements

  1. The rules engine in WF is improved to add support for C# 3.0 extension methods, and for operator overloading . Also the ”new” operator is added to compete the base set of expression types.

Built-in WPF tools for Visual Studio “Orcas”

  1. The Visual Studio designer for WPF was previously released as a CTP. It is not integrated into the development environment and is significantly improved.

Additional WPF Features and Improved Performance

  1. WPF has smoother animations, faster startup and better overall performance. There are also new data types available for data binding with LINQ. Better integration support is now provided for with codename “WPF/E”.

Trên đây là 1 số tính năng mới bên trong .NET framework 3.5 và Visual Studio .NET Orcas (beta).

Chú thích NGen:

NGen là từ viết tắt của Native Image Generator. Đây là 1 công cụ được đưa vào từ .NET 1.x dùng để tạo 1 "native image" cho 1 assembly. Trong .NET, CLR thực thi các mã IL là mã trung gian của .NET (không phải mã nhị phân). Để máy có thể hiểu được, thì nó cần phải được dịch sang mã máy (mã nhị phân). CLR Excution Engine có chứa 1 bộ biên dịch gọi là JIT (Just In Time) để mà chuyển mã IL này sang mã dạng nhị phân (native code) trong lúc chạy. Tuy nhiên, mã nhị phân này sẽ không được lưu lại trên các thiết bị lưu trữ permanant mà nó chỉ được lưu trên bộ nhớ trong Process lifetime. Khi application được restart thì bộ biên dịch JIT phải compile lại các mã IL sang mã native lại.

Bộ NGen này cho phép tạo 1 cái "Native Image" (như là chụp lại cái đoạn mã máy đã được biên dịch) và lưu trên thiết bị lưu trữ trong 1 vùng đặc biệt gọi là NGen Cache - Native Image Cache.

Qua các .NET framework khác nhau, bộ NGen này được tối ưu hóa nhiều hơn với những giải thuật tốt hơn. Nếu gõ vào Start > Run... %windir%\assembly thì có thể thấy thư mục NGen Cache này

Phần tiếp theo: Những cái mới trong C# 3.0

.NET Framework 3.0 (part 1)

Hic, mấy tuần này đang rảnh, nên ngồi đọc tài liệu, cập nhật kiến thức. Mình đã quyết định đi theo hướng công nghệ của MS, chạy theo nó đúng là hụt hơi luôn. .NET 3.0 vừa mới ra, chưa kịp xài, đã ra .NET 3.5, VSS Orcas và SilverLight… hic hic hic

Tranh thủ viết blog, chia sẻ với bạn bè chút kiến thức mới sưu tầm được.

Bài viết này trước hết giải thích một số nền tảng mới trong .NET 3.0.

Trước hết, thì theo đọc qua taì liệu 1 cách sơ bộ thì có thể đưa ra công thức cho .NET 3.0 là

.NET 3.0 = .NET 2.0 + WPF + WCS + WF + WPF



Riêng đối với .NET 3.5 ngoài WPF + WCS + WF + WPF, phần core sử dụng CLR 3.5 còn có thêm 1 cái khá hay đó là LINQ và ASP .NET AJAX được tích hợp các tính năng MS ASP .NET AJAX 1.0 (trước đó code name là Atlas) từ thời .NET 2.0 và khá nhiều tính năng mới được thêm vào. Có thể nói từ .NET 3.0 sang .NET 3.5 là cả 1 break change.

Okie okie, đi chi tiết cho .NET 3.0 trước, thì dưới đây là 1 số tính năng mới của nó

Chúng ta sẽ đi sâu hơn chi tiết từng đề mục:

WPF: Windows Presentation Foundation

WPF là một bộ các controls trong đó có khá nhiều cái là trùng lặp với các control đơn giản trong Windows Form. Tuy nhiên, các control mới hỗ trợ các tính năng về đồ họa và các tương tác một cách có ấn tượng hơn.

Ví dụ như các đối tượng có thể chứa các đối tượng khác như là 1 nội dung của nó. 1 cái button có thể chứa cả 1 cái Grid, trong grid có thể chứa nhiều label, textbox, hình hay bất kỳ các control nào khác. Đó là đặc điểm khá tuyệt vời của WPF, nó cho phép các control thể hiện ở rất nhiều dạng khác nhau cùng với các tương tác khác nhau, hơn là chỉ 1 đòng text.

Các control trong WPF cũng có thể được tô gradient phần background. Lập trình viên có thể định ra cacs style và template sẵn để cho toàn bộ form có 1 cái GUI thống nhất. Nếu như mà mình cần thay đổi 1 cái button từ kiểu linear gradient (đổ màu tuyến tính) từ màu đỏ sang vàng thành radial gradient (đổ màu tuyến tính theo tâm vòng tròn) từ màu trắng sang đen, mình có thể làm rất dễ dàng trong vài giây và chỉ tại 1 chỗ.

Một đặc điểm nữa của các Control trong WPF đó là nó có thể chứa các trigger, và thực hiện số số action nào đó khi nhận được “kích thích” . Ví dụ 1 cái button có thể thay đổi màu sắc, làm bự ra, thu nhỏ lại, hay quay vòng vòng hay nói chung, các hiệu ứng mà con chuột được đưa vào hoặc là đc nhấn lên đó.

Một trong những khái niệm quan trọng nhất trong WPF là sự tách biệt giữa giao diện và code của nó. Từ ý tưởng là người thiết kế giau diện có thể dùng 1 cái tool như là Expression để xây dựng giao diện, và developer sẽ xử lý code cho các đối tượng đó. Hiện tại, thì chương trình Expression ko có đc miễn phí mà nó phải đc trả tiền để có nó, và MS cũng chưa có cho biết là Expression có được có trong Visual Studio hay ko? Hiện tại, với cái giao diện design WPF trong Visual Studio thì nó ko có làm việc tốt lắm với các control của WPF. Hi vọng sẽ có những caỉ tiến hơn trong các phiên bản sau.

Trong WPF cũng có đưa them 1 khái niệm là XAML XAML (Extensible Application Markup Language — đọc là "zammel"), đây là ngôn ngữ mà sẽ định dạng câú trúc cuả WPF và cũng là ngôn ngữ chính để tạo ra SilverLight object.

Tuy nhiên, các WPF control lại ko muốn “làm việc” chung với các Windows Form control. Mình có thể dùng 1 control của Win Form để chứa WPF control và ngược lại, tuy nhiên, nó ko có dễ dàng như việc kéo thả những control thông thường trong 1 cái form.

Ví dụ, control trong Win Form sử dụng Text để define cái text của control đó như Button hay Textbox chẳng hạn. Ngược lại, các WPF control sử dụng Content để define cái mà bên trong nó chứa, có thể là 1 control khác hoặc 1 đoạn text chẳng hạn. Ngoại trừ Window object (là 1 phiên bản trong WPF của Form) thì cần có cả Content chứa các controls khác và cả Title để định nghĩa cái tiêu đề form.

Windows Control cũng sử dụng FontFamily, FontSize, FontStretch, FontStyle, và FontWeight một cách riêng biệt để hiển thị text, nhưng với Control WPF thì sử dụng thuộc tính Font duy nhất với các thuộc tính riêng. Điều này cũng đồng nghĩa là Visual Studio's WPF form designer sẽ ko có tạo ra những dialog có những font đẹp hơn theo ý mình.

WCF - Windows Communication Foundation

Windows Communication Foundation là 1 bộ các công cụ để thực hiện theo Dịch vụ hướng Kiến Trúc (SOA). Nó bao gồm các lớp và method để xây dựng các lớp (class) client và server. Những tool này giúp lập trình viên xây dựng cacs Class một cách rất dễ dàng.

WCF cũng đồng thời cho phép client và server giao tiếp với nhau bằng rất nhiều cách như TCP, HTTP, name pipes hay Message Queue. WCF cũng đồng thời bao gồm các tính năng để cung cấp các giải pháp giao tiếp an toàn giữa client và server.

Tuy nhiên, 1 điểm bất lợi là WCF cung cấp tất cả những option này thì đồng thời, nó cũng yêu cầu cấu hình, cấu hình cho WCF là 1 vấn đề. VSS cũng ko cung cấp nhiều thông tin hướng dẫn làm sao để build một file cấu hình bằng file XML để câú hình client và server ở mức độ mong muôns. Vì vậy, vấn đề cấu hình cho WCF là một khó khăn mà cần cân nhắc khi sử dụng WCF.

WF - Windows Workflow Foundation

Hì, trước tiên, chúng ta cần giải thích vì sao MS lại sử dụng WF cho cụm từ Windows Workflow Foundation mà đúng ra là fải sử dụng WFF? Thực ra, WFF là tên viết tắt của tổ chức World Wrestling Federation, nên MS cũng ko muốn bị kiện tụng gì nữa, cuối cùng đã sử dụng là WF vừa ngắn gọn hơn. Vì vậy, ở 1 số tài liệu, thuật ngữ này được sử dụng là Windows Workflow hoặc Workflow.

WF cung cấp 1 nhóm các lớp (class) mà mô hình hoá từng khía cạnh của 1 workflow của 1 ứng dụng. Những lớp khác nhau đại diện cho những action ví dụ như đợi 1 sự kiện, thực thi theo điều kiện (branching), đợi 1 trong nhiều sự việc xảy ra và thực thi các lệnh tuần tự.

Sau khi thiết kế workflow, 1 workflow engine sẽ di chuyển các đối tượng qua rất nhiều trạng thái trong workflow cho tới khi chúng đến được điều kiện kết thúc.

Windows CardSpace

WC - CardSpace (hay InfoCard) là 1 công cụ để xây dựng hệ thống nhận dạng dựa vào CardSpace đã trên máy client. Ví dụ trên Ebay xây dựng 1 hệ thống cho phép xác định tính đáng tin cậy cuả ngươì mua và người bán. Tương tự, người dùng CardSpace cũng sẽ tạo ra các identities mà người khác ko thể làm giả khi thao tác với chương trình ứng dụng.

CNG - Cryptography API: Next Generation

CNG được MS hứa hẹn là 1 mô hình mới, đơn giả trong việc mã hoá. Nó bao gồm nhiều cách để "plug and play" với các component khác nhau ví dụ như bộ sinh số ngẫu nhiên (có thể được customize). Nó cũng bao gồm các giải thuật mã hoá mới trên thế giới.

Tuy nhiên, có vẻ như không phải là ý tưởng hay khi dùng CNG với managed code. Thư viện CNG ko fải là thư viện .NET (.NET assembly), nó cũng không phải là COM, cũng không phải là 1 kiểu thư viện như *.tbl file

UAC - User Application Control

Nếu ai đã từng sử dụng Vista thì sẽ thấy 1 điều rằng, dù đang login vào quyền Administrator, thì khi cài đặt phần mềm hoặc tương tác 1 số phần hệ thống, thì 1 hộp thoại sẽ hiển thị, và đôi khi, hiển thị cả ô nhập password của admin. Cách làm này nhằm bảo vệ hệ thống được phép truy xuất bởi những người được phép.

UAC hướng tới việc điều khiển các quyền sử dụng của người dùng đối với application, vì vậy, khi lập trình, thì cần lưu ý đến mức độ ảnh hưởng và cần dùng quyền càng ít càng tốt.

Trong .NET, thì các quyền như ghi, sửa, xoá Registry được phép thực thi mà không cần quyền Admin.

Phù, mệt quá, entry sau viết tiếp: So sánh giữa .NET 1.0, 2.0, 3.0 và 3.5

Một số tài liệu tham khảo

Friday, February 2, 2007

Display image in a Web Page

I 've took a lot of times to surf the web to find out the best resolution to display image and scale image with the best quality.

1. Scale image by .NET to produce the best quality
Dim fileName As String = albumlist.SelectedValue & "_" & currentDate & fileExtension
' Create image object from upload stream
Dim img As System.Drawing.Bitmap = System.Drawing.Bitmap.FromStream(.InputStream)
Dim imageFormat = img.RawFormat

Dim thumbSize As New Size
thumbSize = NewthumbSize(img.Width, img.Height)
'Thumb-nail the image to the new size
Dim imgOutput As New Bitmap(img, thumbSize.Width, thumbSize.Height)

'**************THIS HAD TO BE ADDED!!*****************
Dim myresizer As Graphics
myresizer = Graphics.FromImage(imgOutput)
myresizer.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
myresizer.DrawImage(img, 0, 0, thumbSize.Width, thumbSize.Height)
'****************************************************

'Save original image
imgOutput.Save(Path.Combine(Server.MapPath("../photo/images"), fileName), imageFormat)

Note the bold code above, It will produces the best quality image when you try to Zoom or Scale to smaller image.

Beside, I found another way to scale smaller image but, using CSS and HTML only. THe quality is good.

Thursday, January 4, 2007

Removing HTML from the text in ASP
By Konstantin Vasserman.
(Capture link: http://www.codeproject.com/asp/removehtml.asp )
Exploring the options of removing HTML tags from the text in ASP.

Why remove HTML tags?

There could be a number of reasons why you as a developer want to remove HTML tags from the text. The most common situation is when you are going to display some text on the web page and the text was submitted by an unknown user or it came from some other source that you have no control over. You don't have any idea what the content of the text is: it could contain some damaging script or some HTML formatting that will completely mess up the look of your site. It could be that you just don't want any HTML tags in the text because of some application restrictions. You might want to limit the use of HTML to some simple text formatting tags, but restrict the users from using links and inserting images. Whether you have a good reason for that or you just want HTML out of your text because you are a member of "HTML Hatred Club" - you have to find the way to get those tags out of the text. This article will look into the options you have when it comes to removing HTML tags from the text in ASP.

First Option - Disable HTML

First and probably the easiest solution is to just disable HTML tags in the text without removing them. You can do it with Replace() function. For example, if you want to disable all the SCRIPT tags you could do this:

strText = Replace(strText, ", "<script", 1, -1, 1)
or to make sure that all HTML tags are disabled:
strText = Replace(strText, "<", "<")

No opening brackets - no valid HTML tags - no problem. Right?

It is a good (quick) security measure to prevent people from embedding damaging client-side scripts within the text they submit, but it is hardly a user-friendly feature.

The problem with this approach is that all the HTML tags are now shown as well as the rest of the text and it is very hard to read. It's kind of like displaying the HTML source to the user - not a very nice thing to do.

Second Option - Use the brackets

How to make HTML tags disappear from the text? Well, we can just remove them. We can just take everything between opening bracket "<" and closing bracket ">" of HTML tags and remove it. It sounds easy ...

Well, it is easier said than done, especially in VBScript. :-)

People who code in Perl or Java Scripts can actually tell you that it is a piece of cake. They are absolutely right. For example, JavaScript function that removes everything between the brackets could look like this:

function RemoveHTML( strText )
{
var regEx = /<[^>]*>/g;
return strText.replace(regEx, "");
}

For those of you who doesn't know what all of these "/<[^>]*>/g" mean - it's called Regular Expression. "Regular expressions are patterns used to match character combinations in strings." You can learn more about them by following this link: http://developer.netscape.com/docs/manuals/js/client/jsguide/regexp.htm.

Back in VBScript world, for those of us who runs Scripting Engine 5.0 or later (you can check you version by calling ScriptEngineMajorVersion and ScriptEngineMinorVersion functions) we can use RegExp object as well. RemoveHTML function could look like this:

Function RemoveHTML( strText )
Dim RegEx

Set RegEx = New RegExp

RegEx.Pattern = "<[^>]*>"
RegEx.Global = True

RemoveHTML = RegEx.Replace(strText, "")
End Function

It doesn't look too complicated, does it? Providing that you know how to build those patterns ... ;-)

For the rest of VBScript people (who has an older Scripting Engine or doesn't want to mess with the Regular Expressions) writing of your own little parser is the way to go. Below is an example of such a function. My friend Chris Coursey and I used this function in one of our projects a couple of years ago:

Function RemoveHTML( strText )
Dim nPos1
Dim nPos2

nPos1 = InStr(strText, "<")
Do While nPos1 > 0
nPos2 = InStr(nPos1 + 1, strText, ">")
If nPos2 > 0 Then
strText = Left(strText, nPos1 - 1) & Mid(strText, nPos2 + 1)
Else
Exit Do
End If
nPos1 = InStr(strText, "<")
Loop

RemoveHTML = strText
End Function

While all of the above solutions work and do exactly what they were meant to do (remove everything between the brackets), there are at least a couple of problems with this approach:

First of all, because these functions are only take into an account the bracket characters - any brackets within the body of the text that were never meant to be HTML tags will be removed. They will be removed together with any text that happens to be within those brackets. In other words, any attempt by a user to include "<" or ">" characters in the text might cause these functions to produce unpredictable and at the time very ugly results.

On the other hand, these functions remove all the HTML tags unconditionally. You cannot control which tags are removed and which are kept untouched. That is the problem when you want to let your users to enter some harmless HTML tags like "" and "", but remove the other tags.

Third Option - Use IE and other tools

The only way to overcome both of the previously discussed problems is to make your code aware of specific HTML tags that you want to be removed. I am currently unaware of any third-party ASP components that would do the job for you, but they might very well be out there. I did however attempted to write one myself based on MSHTML Library and I've seen that somebody has used Internet Explorer's Application object to produce the desired results of striping HTML tags. Both of these solutions seemed to work, but with IE solution you will most likely get a huge performance hit and both of them don't seem to be very safe things to do according to MSKB:

"It may be desirable to parse HTML files inside a Web server process in response to a browser page request. However, the WebBrowser control, DHTML Editing Control, MSHTML, and other Internet Explorer components may not function properly in an Active Server Pages (ASP) page or other application run in a Web server application." (http://support.microsoft.com/support/kb/articles/Q244/0/85.ASP?LN=EN-US&SD=gn&FR=0)

In other words - think twice before using any IE components on the server side.

Fourth Option - Another VBScript attempt

Having explored all of the above options I have taking a challenge of writing an ASP function in VBScript that would both be intelligent enough to remove only known HTML tags and at the same time would provide the developer with ability to control which tags to remove. Following is the result of this attempt.

A few words about the function:

  • List of the HTML tags to be removed controlled by adding or removing tags from the TAGLIST constant. For example, to leave all tags in the text you must remove B from the TAGLIST. Current list contains every tag listed in index of HTML tags of MSDN Library with the addition of the LAYER tag. Please note that every tag must be surrounded by semi-colons (";") in order for this function to work properly.
  • Both the start and the end tags will be removed. For example, both and tags will be removed.
  • If tag is present in both TAGLIST and BLOCKTAGLIST constants this function will remove everything between the start and the end tag. For example, if SCRIPT tag is included in both TAGLIST and BLOCKTAGLIST everything between tags will be removed.
  • Tags without a closing bracket will not be considered a valid HTML tags and therefore will not be removed. That in compliance with the HTML standard as far as I know.
  • Block tags that does not have an end tag will cause the entire portion of the text from the start tag to the end of the text to be removed. For example, if is missing - everything from to the end of the text will be removed.
  • I've done some performance testing on this function just to get an idea about its speed. It removed a 1000 tags from 24K text string in one second. 2300 tags were removed from 60K text string in about 4.5 seconds. Relatively short string with a few tags - very fast. :-)

Usage of the function is simple:



strPlainText = RemoveHTML(strTextWithHTML)

And here is the function (VB .NET):

Collapse
Function RemoveHTML( strText )
Dim TAGLIST
TAGLIST = ";!--;!DOCTYPE;A;ACRONYM;ADDRESS;APPLET;AREA;B;BASE;BASEFONT;" &_
"BGSOUND;BIG;BLOCKQUOTE;BODY;BR;BUTTON;CAPTION;CENTER;CITE;CODE;" &_
"COL;COLGROUP;COMMENT;DD;DEL;DFN;DIR;DIV;DL;DT;EM;EMBED;FIELDSET;" &_
"FONT;FORM;FRAME;FRAMESET;HEAD;H1;H2;H3;H4;H5;H6;HR;HTML;I;IFRAME;IMG;" &_
"INPUT;INS;ISINDEX;KBD;LABEL;LAYER;LAGEND;LI;LINK;LISTING;MAP;MARQUEE;" &_
"MENU;META;NOBR;NOFRAMES;NOSCRIPT;OBJECT;OL;OPTION;P;PARAM;PLAINTEXT;" &_
"PRE;Q;S;SAMP;SCRIPT;SELECT;SMALL;SPAN;STRIKE;STRONG;STYLE;SUB;SUP;" &_
"TABLE;TBODY;TD;TEXTAREA;TFOOT;TH;THEAD;TITLE;TR;TT;U;UL;VAR;WBR;XMP;"

Const BLOCKTAGLIST = ";APPLET;EMBED;FRAMESET;HEAD;NOFRAMES;NOSCRIPT;OBJECT;SCRIPT;STYLE;"

Dim nPos1
Dim nPos2
Dim nPos3
Dim strResult
Dim strTagName
Dim bRemove
Dim bSearchForBlock

nPos1 = InStr(strText, "<")
Do While nPos1 > 0
nPos2 = InStr(nPos1 + 1, strText, ">")
If nPos2 > 0 Then
strTagName = Mid(strText, nPos1 + 1, nPos2 - nPos1 - 1)
strTagName = Replace(Replace(strTagName, vbCr, " "), vbLf, " ")

nPos3 = InStr(strTagName, " ")
If nPos3 > 0 Then
strTagName = Left(strTagName, nPos3 - 1)
End If

If Left(strTagName, 1) = "/" Then
strTagName = Mid(strTagName, 2)
bSearchForBlock = False
Else
bSearchForBlock = True
End If

If InStr(1, TAGLIST, ";" & strTagName & ";", vbTextCompare) > 0 Then
bRemove = True
If bSearchForBlock Then
If InStr(1, BLOCKTAGLIST, ";" & strTagName & ";", vbTextCompare) > 0 Then
nPos2 = Len(strText)
nPos3 = InStr(nPos1 + 1, strText, " & strTagName, vbTextCompare)
If nPos3 > 0 Then
nPos3 = InStr(nPos3 + 1, strText, ">")
End If

If nPos3 > 0 Then
nPos2 = nPos3
End If
End If
End If
Else
bRemove = False
End If

If bRemove Then
strResult = strResult & Left(strText, nPos1 - 1)
strText = Mid(strText, nPos2 + 1)
Else
strResult = strResult & Left(strText, nPos1)
strText = Mid(strText, nPos1 + 1)
End If
Else
strResult = strResult & strText
strText = ""
End If

nPos1 = InStr(strText, "<")
Loop
strResult = strResult & strText

RemoveHTML = strResult
End Function

Konstantin Vasserman



private string RemoveHTML(string strText)
{

string TAGLIST
= ";!--;!DOCTYPE;A;ACRONYM;ADDRESS;APPLET;AREA;B;BASE;BASEFONT;" +
"BGSOUND;BIG;BLOCKQUOTE;BODY;BR;BUTTON;CAPTION;CENTER;CITE;CODE;" +
"COL;COLGROUP;COMMENT;DD;DEL;DFN;DIR;DIV;DL;DT;EM;EMBED;FIELDSET;" +
"FONT;FORM;FRAME;FRAMESET;HEAD;H1;H2;H3;H4;H5;H6;HR;HTML;I;IFRAME;IMG;" +
"INPUT;INS;ISINDEX;KBD;LABEL;LAYER;LAGEND;LI;LINK;LISTING;MAP;MARQUEE;" +
"MENU;META;NOBR;NOFRAMES;NOSCRIPT;OBJECT;OL;OPTION;P;PARAM;PLAINTEXT;" +
"PRE;Q;S;SAMP;SCRIPT;SELECT;SMALL;SPAN;STRIKE;STRONG;STYLE;SUB;SUP;" +
"TABLE;TBODY;TD;TEXTAREA;TFOOT;TH;THEAD;TITLE;TR;TT;U;UL;VAR;WBR;XMP;";

const string BLOCKTAGLIST = ";APPLET;EMBED;FRAMESET;HEAD;NOFRAMES;NOSCRIPT;OBJECT;SCRIPT;STYLE;";

int nPos1 = 0;
int nPos2 = 0;
int nPos3 = 0;
string strResult = "";
string strTagName = "";
bool bRemove;
bool bSearchForBlock;

nPos1 = strText.IndexOf("<"); while (nPos1 >= 0)
{
nPos2 = strText.IndexOf(">", nPos1 + 1);
if (nPos2 >= 0)
{
strTagName = strText.Substring(nPos1 + 1, nPos2 - nPos1 - 1);

strTagName = strTagName.Replace("r", " ").Replace("n", " ");

nPos3 = strTagName.IndexOf(" ");

if (nPos3 > 0) strTagName = strTagName.Substring(0, nPos3);

if (strTagName.Substring(0, 1) == "/")
{
strTagName = strTagName.Substring(1);
bSearchForBlock = false;
}
else bSearchForBlock = true;

if (TAGLIST.IndexOf(";" + strTagName.ToUpper() + ";", 0) >= 0)
{
bRemove = true;
if (bSearchForBlock)
{
if (BLOCKTAGLIST.IndexOf(";" + strTagName.ToUpper() + ";") >= 0)
{
nPos2 = strText.Length;
nPos3 = strText.IndexOf(" if (nPos3 > 0) nPos3 = strText.IndexOf(">", nPos3 + 1);
if (nPos3 > 0) nPos2 = nPos3;
}
}
}
else bRemove = false;

if (bRemove)
{
strResult = strResult + strText.Substring(0, nPos1);
strText = strText.Substring(nPos2 + 1);
}
else
{
strResult = strResult + strText.Substring(nPos1);
strText = strText.Substring(nPos1 + 1);
}
}
else
{
strResult = strResult + strText;
strText = "";
}

nPos1 = strText.IndexOf("<"); } strResult = strResult + strText; strResult = strResult.Replace("rnrn", "rn"); return strResult; }

Friday, December 15, 2006


SqlCacheDependency Class

Technical Concept



Author: Minh Nguyen


Version 0.1

Status: new

Author

AUTHOR

FIRM/DEPARTMENT

Minh Nguyen

Software Development

HISTORY

VERSION

DATE

CHANGES

0.1

14.09.2006

First draft

OPEN ISSUES

From

Issues

Date

Status





Content

1 Introduction 4

2 How to use 4

2.1 Web.config 4

Above is the a piece configuration in Web.config file. 5

2.2 Enable Service Broker in SQL Server 2005 5

2.2.1 Create Service Broker endpoint 5

2.2.2 Enable Service Broker for a database 5

2.3 Enable Query Notification in SQL Server 2005 6

2.3.1 Enable Query Notification in SQL Server 2005 by Command Line 6

2.3.2 Enable Query Notification in SQL Server 2005 by Programming 6

2.4 Code using 7

3 Some issues 7

3.1 Performance 7

3.2 SQL Command 7

3.3 Supported SELECT Statements 8

3.4 Duplicate Subscriptions 9

4 Reference 9

In ASP.NET 2.0, caching has been improved in a couple of notable ways. Probably the most interesting feature is the introduction of database-triggered cache invalidation. In ASP.NET 1.x, you can invalidate a cached item based on some pre-defined conditions such as change in an XML file or change in another cache item. Using this feature, you can remove or invalidate an item from the cache when the data or another cached item changes. However, the ASP.NET 1.x Cache API does not allow you to invalidate an item in the cache when data in a SQL Server database changes. This is a very common capability most applications will require. ASP.NET 2.0 addresses this by providing the database triggered cache invalidation capability to ensure that the items in the cache are kept up-to-date with the changes in the database. You can accomplish this using any one of the following methods.

· Declarative Output caching - This is similar to declarative output caching in ASP.NET 1.x, wherein you configure caching by specifying the OutputCache directive and their related attributes.

· Programmatic Output caching - In this method, you will use the SqlCacheDependency object programmatically to specify the items to be cached and set their attributes.

· Cache API - In this option, you will use the static methods of the Cache class such as Insert, Remove, Add and so on to add or remove items from the ASP.NET cache, while still using the SqlCacheDependency object to trigger the cache invalidation.

Another important caching feature in ASP.NET 2.0 is the ability to create custom cache dependencies, which is not possible with ASP.NET 1.x Cache API. To accomplish this, you need to inherit from the CacheDependency class. Since the CacheDependency is a sealed class in ASP.NET 1.x, you can't inherit and extend it. However, in ASP.NET 2.0, this is no longer the case. You can inherit from CacheDependency class and create your own custom cache dependencies. This opens up a world of opportunities where you can roll your own custom cache dependencies required for a particular class of applications. For example, you can create a StockPriceCacheDependency class that automatically invalidates the cached data when the stock price changes.

This document will mention to SQL Server 2005 only, the DBMS that use in the project.

The main points are:

· How to use: explain some important features, notices and example coding to use SqlCacheDependency.

· Some issues: answer some technical question about this class.

To use this class, you need to configure some setting on SQL Server 2005; this is optional step, Web Application configuration and use code as below sample.

2.1 Web.config

In order to let the Web application understand and run the SqlCacheDependency modules, below configuration need to add to Configuration file (Web.config, app.config).

...

<connectionStrings>

<add name="LP_Shop_Instance" connectionString="Database=LP_Shop_Test;Server=172.16.6.3SQL2005;uid=lp_shop;pwd=lp_shop;" providerName="System.Data.SqlClient"/>

connectionStrings>

...

<system.web>

<caching>

<sqlCacheDependency enabled="true" pollTime="1000">

<databases>

<add name="LP_Shop_Instance" connectionStringName="LP_Shop_Instance" pollTime="1000"/>

databases>

sqlCacheDependency>

caching>

....

system.web>

Above is the a piece configuration in Web.config file.

  • ConnectionString: represent the connection string to database
  • pollTime: the interval polling in millisecond, if no invalidation occurs
  • connectionStringName: the name of ConnectionString declare in ConnectionString section

2.2 Enable Service Broker in SQL Server 2005

To use the SqlCacheDependency correctly, the Service broker must be enable.

2.2.1 Create Service Broker endpoint

Use SQL Server Management Studio or a similar tool to execute the following command to create a Service Broker endpoint:

USE master;

GO

CREATE ENDPOINT BrokerEndpoint

STATE = STARTED

AS TCP ( LISTENER_PORT = 4037 )

FOR SERVICE_BROKER ( AUTHENTICATION = WINDOWS );

GO

2.2.2 Enable Service Broker for a database

Enable Service Broker for a given database (for example, LP_WebShopLabel_DB) with this command:

ALTER DATABASE LP_WebShopLabel_DB SET ENABLE_BROKER;

GO

Now you can use SQL cache dependencies against the LP_WebShopLabel_DB database.

2.3 Enable Query Notification in SQL Server 2005

Once you configure the table to send notifications, any time data in the table changes, it notifies ASP.NET to invalidate the specific item in the cache. For the purposes of this article, consider the aspnet_regsqlcache utility to configure the tables. Basically this utility creates an extra table named AspNet_SqlCacheTablesForChangeNotification that is used to keep track of the changes to all the monitored tables in the database. It also creates a number of triggers and stored procedures to enable this capability.

There are 2 ways to enable the Query Notification in SQL Server 2005:

  • By aspnet_regsqlcache utility
  • By programming

2.3.1 Enable Query Notification in SQL Server 2005 by Command Line

To run the aspnet_regsqlcache utility, open up the Visual Studio .NET command prompt and enter the command shown in the following screenshot.

In the above command:

S - Name of the Server

U - User ID to use to connect to the SQL Server

P - Password to use to connect to the SQL Server

d - Specifies the name of the database

t - Table to configure

et - enables the tables for SQL Server database triggered invalidation

With SQL Server 2005, the above configurations are not necessary. Moreover the cache invalidating mechanism works through a highly efficient notification model, wherein the Notification Delivery Service component of SQL Server directly notifies IIS using TCP Port 80 when the data in a SQL Server changes.

2.3.2 Enable Query Notification in SQL Server 2005 by Programming

To enable the Query notification in SQL Server 2005, in the code line, add the following code:

SqlCacheDependencyAdmin.EnableNotifications(DB.CurrentConnectionString); SqlCacheDependencyAdmin.EnableTableForNotifications(DB.CurrentConnectionString, "CMRC_Products");

In the above example,

  • The SqlCacheDependency is the member of namespace: System.Web.Caching
  • DB.CurrentConnectionString represents the ConnectionString to Database.
  • “CMRC_Products” is the name of the table need to be enable Query notification.

This code of line will enable the table CMRC_products for any change will be notified to the web application.

We also can get the list of table has notification enabled by:

SqlCacheDependencyAdmin.GetTablesEnabledForNotifications();

2.4 Code using

After enable the table need to be notify, we can use it in the code.

Example: on Page_Load event:

DataSet ds;

ds = (DataSet)Cache["Customer"];

if (ds == null)

{

System.Data.SqlClient.SqlCommand sqlCmd = new

System.Data.SqlClient.SqlCommand();

sqlCmd.CommandText = "Select ProductID, Product From dbo.CMRC_Products";

sqlCmd.Connection = new

System.Data.SqlClient.SqlConnection(DB.CurrentConnectionString);

SqlCacheDependencyAdmin.EnableNotifications(DB.CurrentConnectionString); SqlCacheDependencyAdmin.EnableTableForNotifications(DB.CurrentConnectionString, "CMRC_Products");

SqlCacheDependency dependency = new SqlCacheDependency(sqlCmd);

Database db = DatabaseFactory.CreateDatabase(DB.DatabaseInstance);

DbCommand dbCommand = db.GetStoredProcCommand(sqlCmd.CommandText

ds = db.ExecuteDataSet(dbCommand);

this.Cache.Insert("Products", ds, dependency);

Label1.Text = "Page created on: " + DateTime.Now.ToString();

}

else

Label1.Text = "
Get from cache"
;

GridView1.DataSource = ds;

GridView1.DataBind();

3.1 Performance

SqlCacheDependency improves the performance of the ASP .NET website a lot. Especially the feature notification help the site update the latest version of data from the Database immediately.

When try to run the Query Profiler to monitor the traffic between the Database Server and the application using the SqlCacheDependency and with the application without using SqlCacheDependency, the performance is not increase so much, but the traditional caching method will not update the data immediately but after an interval.

Question: If in 1000 records of data, one record change while the data is in cache, the SqlCacheDependency is enough intelligent to replace only the record changed in the cache or all of data?

Answer: All the data will be pulled out. But the duration will be reduced a lot.

3.2 SQL Command

In general, you can request notification for any query that can be used to create an indexed view. You can set up notifications for the following statements:

  • SELECT
    For requirements and limitations specific to SELECT, see "Supported SELECT Statements" below. For more information on the SELECT statement.
  • EXECUTE
    In this case, SQL Server registers a notification for the command executed rather than the EXECUTE statement itself. The command must meet the requirements and limitations for a SELECT statement. For more information on the EXECUTE statement.

When a command that registers a notification contains more than one statement, the Database Engine creates a notification for each statement in the batch.

If a subscription request is made for a batch or stored procedure, a separate subscription request is made for each statement executed within the batch or stored procedure.

EXECUTE statements will not register a notification, but will flow the notification request to the executed command. If it is a batch, the context will be applied to the executed statements and the same rules described above apply.

But, when I run the SQL Profiler, I found that when registering Execute notification, I found it sometime does not works until the Cachce expired.

3.3 Supported SELECT Statements

Query notifications are supported for SELECT statements that meet the following requirements:

  • The projected columns in the SELECT statement must be explicitly stated, and table names must be qualified with two-part names. Notice that this means that all tables referenced in the statement must be in the same database.
  • The statement may not use the asterisk (*) or table_name.* syntax to specify columns.
  • The statement may not use unnamed columns or duplicate column names.
  • The statement must reference a base table.
  • The statement must not reference tables with computed columns.
  • The projected columns in the SELECT statement may not contain aggregate expressions unless the statement uses a GROUP BY expression. When a GROUP BY expression is provided, the select list may contain the aggregate functions COUNT_BIG() or SUM(). However, SUM() may not be specified for a nullable column. The statement may not specify HAVING, CUBE, or ROLLUP.
  • A projected column in the SELECT statement that is used as a simple expression must not appear more than once.
  • The statement must not include PIVOT or UNPIVOT operators.
  • The statement must not include the INTERSECT or EXCEPT operators.
  • The statement must not reference a view.
  • The statement must not contain any of the following: DISTINCT, COMPUTE or COMPUTE BY, or INTO.
  • The statement must not reference server global variables (@@variable_name).
  • The statement must not reference derived tables, temporary tables, or table variables.
  • The statement must not reference tables or views from other databases or servers.
  • The statement must not contain subqueries, outer joins, or self-joins.
  • The statement must not reference the large object types: text, ntext, and image.
  • The statement must not use the CONTAINS or FREETEXT full-text predicates.
  • The statement must not use rowset functions, including OPENROWSET and OPENQUERY.
  • The statement must not use any of the following aggregate functions: AVG, COUNT(*), MAX, MIN, STDEV, STDEVP, VAR, or VARP.
  • The statement must not use any nondeterministic functions, including ranking and windowing functions.
  • The statement must not contain user-defined aggregates.
  • The statement must not reference system tables or views, including catalog views and dynamic management views.
  • The statement must not include FOR BROWSE information.
  • The statement must not reference a queue.
  • The statement must not contain conditional statements that cannot change and cannot return results (for example, WHERE 1=0).
  • The statement can not specify READPAST locking hint.
  • The statement must not reference any Service Broker QUEUE.
  • The statement must not reference synonyms.
  • The statement must not have comparison or expression based on double/real data types.

3.4 Duplicate Subscriptions

Submitting a duplicate of an active subscription causes the existing subscription to be renewed using the new specified time-out value. A duplicate subscription is one that meets the following conditions:

  • The query is submitted by the same user under the same database context.
  • The same template, parameter values, notification ID, and delivery location are used.

This means that if a notification is requested for identical queries, only one notification is sent. This applies to a query duplicated in a batch, or to a query in a stored procedure that is called multiple times.