1. Trang chủ
  2. » Luận Văn - Báo Cáo

Net va c cung voi mot so van de nang cao trong 185550

72 0 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Giới thiệu sơ bộ về nền .NET và ngôn ngữ C#
Định dạng
Số trang 72
Dung lượng 354,44 KB

Cấu trúc

  • Phần I: Giới thiệu sơ bộ về nền .NET và ngôn ngữ C# (6)
    • I. Giới thiệu sơ bộ về .NET (6)
      • I.1. Giới thiệu chung về nền .NET (.NET platform) (7)
      • I.2. KiÕn tróc ph©n líp nÒn .NET (7)
      • I.3. Những đặc trng của nền .NET (8)
        • I.3.1. Phát triển đa ngôn ngữ (8)
        • I.3.2. Chơng trình ứng dụng độc lập với hệ điều hành và bộ vi xử lí (8)
        • I.3.3. Quản lí bộ nhớ tự động (8)
        • I.3.4. Hỗ trợ phiên bản (9)
      • I.4. Những thành phần của nền .NET (9)
        • I.4.1. CLR (9)
        • I.4.2. Mã quản lí và mã không quản lí ( Managed/Unmanaged Code ) (10)
        • I.4.3. Ngôn ngữ trung gian , hệ thống kiểu thông thờng và CLS (10)
        • I.4.4. Th viện lớp cơ sở của .NET (11)
        • I.4.5. Assembly và metadata (11)
        • I.4.6. Chơng trình dịch Just in time (11)
        • I.4.7. Quản lí bộ nhớ ( Garbage Collection ) (11)
        • I.4.8. Vòng đời của mã (12)
    • II. Giới thiệu sơ bộ ngôn ngữ lập trình C# (0)
      • II.1. Lập trình hớng đối tợng trong C# (12)
      • II.2. Những đặc điểm của ngôn ngữ C# (13)
        • II.2.1. Các toán tử (13)
        • II.2.2. Các kiểu dữ liệu (13)
        • II.2.3. Các câu lệnh (14)
        • II.2.4. Cấu tạo của một chơng trình C# (14)
      • II.3. C# và những vấn đề nâng cao (15)
        • II.3.1. C# với cơ sở dữ liệu (15)
        • II.3.2. C# víi Internet (16)
  • Phần II: Đồ họa trong C# (17)
    • I. Giới thiệu về GDI+ (17)
    • II. Kiến trúc của GDI+ (17)
      • II.1. Đồ họa Vector 2D (17)
      • II.2. Hình ảnh (18)
      • II.3. In ấn v hiển thị font chữ à hiển thị font chữ (18)
    • III. Kiến trúc lớp của GDI+ (18)
    • IV. Mét sè ®iÓm míi trong GDI+ (19)
      • IV.1. Bút vẽ Gradient (19)
    • IV. 2. §êng cong Spline (20)
      • IV.3. Đối tợng đồ họa độc lập (20)
      • IV.4. Chức năng chuyển đổi v đối t à hiển thị font chữ ợng ma trận (20)
      • IV.5. Vùng ảnh co giãn đợc (20)
      • IV.6. Đổ bóng Alpha (21)
    • V. Thay đổi trong mô hình lập trình (21)
      • V.1. Ngữ cảnh thiết bị, Handles v các đối t à hiển thị font chữ ợng đồ họa (21)
      • V.2. Bút vẽ, bút phủ, đồ họa, hình ảnh v Font chữ à hiển thị font chữ (22)
    • VI. Giới thiệu các đối tợng đồ họa cơ bản trong GDI+ (22)
      • VI.1. Đồ họa Vector (22)
      • VI.2. Hình ảnh v Metafile à hiển thị font chữ (23)
      • VI.3. Các loại hệ tọa độ (24)
      • VI.4. Các phép chuyển đổi (24)
  • Phần III: Đa luồng trong C# (26)
    • I. Khái niệm đa luồng (26)
      • I.1. Đa nhiệm ( multitasking ) (26)
      • I.2. Đa luồng ( multitasking) (26)
    • II. Đa luồng trong C# (27)
      • II.1. Cấu trúc các lớp điều khiển luồng của C# (27)
      • II.2. Tổng quát các phơng thức của lớp Thread (29)
        • II.2.1. Tạo luồng ( create thread ) (29)
        • II.2.2. Nhập luồng ( join thread ) (30)
        • II.2.3. Dừng một luồng (31)
        • II.2.4. Hủy một luồng (31)
      • II.3. Vòng đời của một luồng (31)
      • II.4. Sự u tiên của luồng và định thời gian biểu cho luồng (32)
      • II.5. Đồng bộ hóa các luồng (33)
        • II.5.1. Líp Interlocked (34)
        • II.5.2. Sử dụng lệnh C# lock (34)
        • II.5.3. Monitor (34)
  • Phần IV: XML và C# (38)
    • I. Lịch sử các ngôn ngữ đánh dấu (38)
      • I.1. Khái niệm “đánh dấu” (markup) (38)
      • I.2. Ngôn ngữ đánh dấu (40)
    • II. Tổng quan về ngôn ngữ XML (41)
      • II.1. Ngôn ngữ XML là gì? (41)
      • II.2. Các u điểm của XML (41)
      • II.3. Các ứng dụng XML (42)
        • II.3.1. Mathematical Markup Language (MathML) (42)
        • II.3.2. Resource Description Framework(RDF) (42)
        • II.3.3. XML Linking Language(XLink) (42)
        • II.3.4. Synchronized Multimedia Intergration Language(SMIL) (42)
        • II.3.5. Extensible Stylesheet Language(XSL) (42)
      • II.4. Tơng lai XML (42)
    • III. Cấu trúc và cú pháp XML (43)
      • III.1. CÊu tróc XML (43)
        • III.1.1. CÊu tróc logic (44)
        • III.1.2. CÊu tróc vËt lÝ (44)
      • III.2. Cú pháp XML (45)
        • III.2.1. Các thẻ gán và phần tử (45)
        • III.2.2. Các thuộc tính và chú giải (46)
    • IV. XML trong C# (46)
      • IV.1. Tạo một tài liệu XML (47)
      • IV.2. Duyệt tài liệu XML (49)
      • IV.3. Quá trình Serializing (50)
      • IV.4. Quá trình Deserializing (52)
  • Phần V: Lập trình mạng trong C# (54)
    • I. Giới thiệu về lập trình mạng (54)
      • I.1. Nhận dạng máy (54)
      • I.2. Socket (55)
      • I.3. Server phôc vô nhiÒu clients (58)
    • II. Giao tiÕp víi Web (60)
      • II.1. Gửi và nhận các yêu cầu HTTP (60)
      • II.2. Các yêu cầu Web không đồng bộ (62)
      • II.3. Dịch vụ Web (62)
  • Phần VI: Một vài so sánh C# với các ngôn ngữ khác (64)
    • I. Sự khác nhau giữa C# và C/C++ (64)
      • I.1. Về môi trờng (64)
      • I.2. Về các lệnh (64)
      • I.3. Về tổ chức chơng trình (65)
    • II. Sự khác biệt giữa C# và Java (65)
      • II.1. Về kiểu dữ liệu (65)
      • II.2. Về truy cập thành phần (66)
      • II.3. Các tham số ref và out (66)
      • II.4. Giao diện (Interfaces) (66)
      • II.5. Về 2 từ khoá khai báo import và using (67)
    • III. Sự khác biệt giữa C# và VB 6.0 (67)
  • Tài liệu tham khảo (70)
    • I. Mô tả chơng trình minh họa (71)
    • II. Hớng dẫn sử dụng chơng trình (72)
    • III. Hớng dẫn cài đặt chơng trình (72)

Nội dung

Giới thiệu sơ bộ về nền NET và ngôn ngữ C#

Giới thiệu sơ bộ về NET

I.1 Giới thiệu chung về nền NET (.NET platform)

Nền NET là một khái niệm mới trong khoa học máy tính; nó vợt ra ngoài khuôn khổ của một ngôn ngữ lập trình, một bộ th viện; nó cha phải là một hệ điều hành, chúng ta có thể hiểu đơn giản nó là một nền để từ đó có thể phát triển các ứng dụng cả trên Windows lẫn trên Internet thuận tiện hơn Nền NET đợc thiết kế để phục vụ các mục đích sau: o Cung cấp một môi trờng lập trình hớng đối tợng tuyệt đối, mã của chơng trình đợc thực thi trên một máy hay cững có thể thực thi từ một máy từ xa thông qua Internet. o Giảm thiểu tối đa xung đột giữa các version của một phần mềm o Đem lại một môi trờng cho phép các ngôn ngữ lập trình có thể giao tiếp với nhau, tích hợp với nhau

Chú ý: chúng ta cũng cần phải phân biệt giữa hai thuật ngữ: NET và nền NET .NET bao gồm 3 thành phần cơ bản : o Nền NET: một nền cho phép phát triển các ứng dụng o Các sản phẩm NET: bao gồm tất cả các sản phẩm của Microsoft dựa trên nền NET. o Các dịch vụ NET: các dịch vụ đợc cung cấp bởi Microsoft phục vụ cho việc phát triển các ứng dụng chạy trên nền NET

Nh vậy nền NET chỉ là một thành phần của NET.

Nền NET gồm hai thành phần chính: Common language runtime ( CLR ) và th viện lớp nền NET Hai thành phần này sẽ đợc trình bày cụ thể ở những phần sau.

I.2 KiÕn tróc ph©n líp nÒn NET

Hình 1 biểu diễn kiến trúc nền NET Mỗi ngôn ngữ thuộc gia đình NET ( phiên bản đầu tiên gồm các ngôn ngữ : VC.NET, VB.NET, C#, sau đó có thêm VJ# )

H×nh 1 KiÕn tróc nÒn NET

8 đều đợc dịch sang ngôn ngữ trung gian Microsoft ( MSIL hay gọi ngắn là IL ) – ngôn ngữ dựa theo tiêu chuẩn của Common Language Specification ( CLS ) Có 3 loại ứng dụng cơ bản là: các ứng dụng Web, các dịch vụ Web, các ứng dụng Form trên Windows Những ứng dụng này sử dụng các đối tợng, phơng thức từ th viện lớp cơ sở và chạy trong môi trờng CLR.

I.3 Những đặc trng của nền NET

Những đặc trng chủ chốt của nền NET chủ yếu nằm trong CLR, th viện lớp cơ sơ và CLS Chúng em chỉ xin trình bày một số đặc trng chúng em cho là dễ nhận biết và nắm bắt nhất

I.3.1 Phát triển đa ngôn ngữ

Trớc đây, vấn đề sử dụng đa ngôn ngữ ( multilanguage ) hay giao thoa ngôn ngữ lập trình ( cross – language ) đã đợc đề cập nhiều khi phát triển các ứng dụng. Đa ngôn ngữ có thể hiểu là việc sử dụng nhiều ngôn ngữ phát triển một ứng dung, mỗi ngôn ngữ viết lên một phần ứng dụng Với giải pháp này, ngời lập trình có thể sử dụng một ngôn ngữ mà mình quen thuộc kết hợp sử dụng lại những đoạn mã đợc viết trên những ngôn ngữ khác phù hợp với mục đích của một phần chơng trình nhất định để xây dựng lên một ứng dụng hoàn chỉnh Một phơng pháp truyền thống để thực hiện giải pháp này là xây dựng nên các th viện động dll Phơng pháp này đợc áp dụng trong VS 6.0 Mỗi ngôn ngữ đều có thể xây dựng nên một th viện dll Một ngôn ngữ khác sẽ sử dụng file dll đó nh là một phần th viện của mình Phơng pháp th hai là sử dụng mô hình đối tợng hớng thành phần – COM ( trong đề tài này sẽ không trình bày về COM, ở đây chúng em chỉ điểm qua) Cả hai phơng pháp trên đều sử dụng ngôn ngữ định nghĩa giao diện ( IDL ) Với nền NET, chúng ta có thể thực hiện việc phối hợp ngôn ngữ dễ dàng hơn Nền NET cho phép ngôn ngữ này có thể tích hợp với ngôn ngữ khác bằng việc sử dụng ngôn ngữ trung gian là MSIL Tất cả các ngôn ngữ khi soạn thảo có thể khác nhau, sau đó đợc dich bởi một chơng trình dịch thích hợp, chúng đều trở thành dạng ngôn ngữ trung gian, khác biệt giữa các ngôn ngữ hoàn toàn bị xoá bỏ Ngôn ngữ trung gian sẽ đợc đa vào CLR để thực thi.

I.3.2 Chơng trình ứng dụng độc lập với hệ điều hành và bộ vi xử lí

Ngôn ngữ trung gian IL là ngôn ngữ độc lập với bộ vi xử lí, nó là ngôn ngữ ở cấp cao hơn ngôn ngữ máy Khi nào cần thực thi, IL sẽ đợc dịch ra ngôn ngữ máy thích hợp Bất cứ hệ điều hành nào hỗ trợ nền NET thì ứng dụng NET sẽ chạy và không gặp khó khăn gì Đối với các hệ điều hành thuộc họ Windows từ Win 98 trở nên đều hỗ trợ nền NET Tháng 6 – 2001, khi mới cho ra đời NET, Microsoft đã thông báo rằng họ đã đạt đợc thoả thuận phát triển NET trên Unix, tuy nhiên đến nay vẫn cha có kết quả chính thức Tháng 10 – 2001, Microsoft cho phép Ximian, ngời đã phát triển giao diện GNOME thông dụng trên Linux, phát triển một chơng trình dịch C# và CLR trên Linux Phiên bản đầu tiên có tên Mono có thể tìm trên www.go- mono.net Công việc hiện đang tiến hành ở giai đoạn xây dựng th viện cơ sở trên Linux.

I.3.3 Quản lí bộ nhớ tự động

Rò rỉ bộ nhớ luôn là vấn đề phức tạp trong lập trình khi ta không quản lý nổi những vùng nhớ đã đợc cấp phát Trong Visual Basic, quản lý bộ nhớ đợc thực hiện bởi kĩ thuật đếm số lần truy cập Trong C và C++, cách tốt nhất để quản lý bộ nhớ là tự mình trả lại cho hệ điều hành những vùng nhớ không dùng nữa Trong NET, có một bộ phận là GC( Garbage Collection ) làm nhiệm vụ thu hồi lại vùng nhớ hiệu quả hơn những cách trên.

Memory Management Including Garbage Collection Execution Support

Những lập trình viên đã từng lập trình với th viện động DLL chắc hẳn đều biết đến thuật ngữ ‘DLL Hell’ DLL Hell có thể miêu tả nh sau : bạn đang sử dụng một chơng trình ứng dụng với một DLL phiên bản 1.0, sau đó bạn cài thêm một ứng dụng khác cũng sử dụng một DLL giống nh vậy với phiên bản 1.1 Khi đó ứng dụng cữ lập tức sẽ có vấn đề, có thể không chạy Khi bạn thay thế DLL đó với DLL phù hợp với ứng dụng cũ thì ứng dụng mới lại không chạy Trong NET, các thành phần của đối t- ợng luôn đợc phân tách riêng rẽ, một ứng dụng chỉ load những thành phần đã đợc xây dựng, kiểm tra chạy thử với ứng dụng đó Sau khi một ứng dụng đã cài đặt và chạy thử thành công thì nó luôn chạy .NET thực hiện vấn đề này bằng cách sử dụng thêm thành phần là assemblies Những thành phần đợc đóng gói lại trong một assembly. Assembly có chứa thông tin về phiên bản, và CLR trong NET sẽ sử dụng thông tin này để nạp đúng những thành phần phục vụ cho ứng dụng

I.4 Những thành phần của nền NET

Nh chúng ta đã xem ở phần trớc, có nhiều thành phần trong nền NET Trong phần này chúng ta sẽ trình bày các thành phần nổi bật về tính chất và vai trò của chúng trong cả hệ thống.

CLR có thể đợc coi nh trái tim của nền NET CLR nằm ở cấp cuối cùng trong sơ đồ phân cấp của nền NET, trực tiếp giao tiếp với hệ điều hành hay các thiết bị phần cứng Vai trò của nó là nhận mã IL, dịch chuyển sang mã máy thích hợp Từ IL trở xuống CLR giống nhau cho mọi ngôn ngữ thuộc dòng NET, điều này giải quyết đợc vấn đề đa ngôn ngữ trong một ứng dụng

I.4.2 Mã quản lí và mã không quản lí ( Managed/Unmanaged Code )

Những mã đợc soạn thảo, dịch nhằm mục đích đợc chạy trong môi trờng CLR thì đợc gọi là mã mã quản lí ( managed code ) Có thể hiểu đơn giản hơn, mã quản lí là loại mã mà chơng trình thực thi mã đó đợc quản lí bởi CLR và nó đợc thừa hởng mọi dịch vụ mà CLR có Thông thờng, mã quản lí là những mã đợc tích hợp sẵn ở trong các th viện lớp hay những mã đợc dịch bởi một chơng trình dịch tuân theo chuẩn CLS tạo ra ngôn ngữ trung gian Mã không quản lí (unmanaged code) là những mã không đợc soạn thảo, dịch trong môi trờng NET và không nhằm mục đích chạy trong CLR tuy nhiên CLR vẫn nạp những mã này vào chạy, nó chỉ không hỗ trợ các dịch vụ cho loại mã này Điển hình cho loại mã này là các th viện DLL có từ tr- ớc NET và th viện Windows APIs, những chơng trình NET sử dụng Windows APIs có nghĩa là nó đã sử dụng mã không quản lý.

I.4.3 Ngôn ngữ trung gian , hệ thống kiểu thông thờng và CLS

Ngôn ngữ trung gian MSIL trong NET, hệ thống kiểu thông thờng và CLS là

3 yếu tố gắn liền với nhau tạo nên khả năng phối hợp đa ngôn ngữ và độc lập với môi trờng của các ứng dụng NET

Hệ thống kiểu thông thờng ( common type system ) bao gồm các kiểu dữ liệu mà các ngôn ngữ NET có thể sử dụng cũng nh qui cách ngời dùng phải tuân theo để xây dựng nên những kiểu dữ liệu của ngời dùng Các kiểu dữ liệu trong hệ thống kiểu thông thờng đợc chia thành 2 loại :

 Loại tham trị: những kiểu tham trị trực tiếp lu trữ các dữ liệu, đợc cấp phát ở vùng nhớ stack Những dữ liệu kiểu này thờng là kiểu dữ liệu xây dựng sẵn nh Int, long, boolean, hay kiểu struct do ngời dùng định nghĩa.

Giới thiệu sơ bộ ngôn ngữ lập trình C#

đề này, NET đa ra hệ thống thu gom bộ nhớ GC Khi chơng trình đòi cấp phát thêm bộ nhớ, bộ phận cấp phát bộ nhớ trong phần quản lí bộ nhớ trong CLR sẽ thc hiện, nếu không còn đủ bộ nhớ nó sẽ thông báo là không còn bộ nhớ để cấp phát GC bắt chạy, nó giả định rằng tất cả mọi thứ trong bộ nhớ đều có thể thu hồi Sau đó, nó xem toàn bộ bộ nhớ dành cho chơng trình ứng dụng, xây dựng nên một đồ thị diễn tả tất cả các vùng bộ nhớ đợc tham chiếu bởi chơng trình và tham chiếu lẫn nhau Sau xây dựng xong đồ thị, GC tiến hành thu gọn bộ nhớ Heap bằng cách di chuyển tất cả các vùng nhớ thật sự dùng về vị trí mới bắt đầu tại một vùng nhớ Heap còn trống Cuối cùng nó cập nhật lại các con trỏ trỏ đến các vùng bộ nhớ vừa đợc di chuyển Chúng ta có thể thấy dờng nh GC thực hiện rất nhiều việc, tuy nhiên nó đợc thực thực hiện tự động bằng CLR, giảm nhẹ đi rất nhiều công việc của ngời lập trình.

Trong phần này, chúng em sẽ giới thiệu về trình làm việc của một ứng dụng NET từ khi soạn thảo mã nguồn đến khi chạy chơng trình :

 Bắt đầu từ việc soạn thảo mã nguồn trên một ngôn ngữ NET quen thuộc trên một hệ soạn thảo văn bản thông thờng.

 Dùng một chơng trình dịch NET dịch mã nguồn ra mã IL, đồng thời xây dựng assembly cho ứng dụng.

 Khi chơng trình ứng dụng thực thi, hệ điều hành sẽ đọc header của ch- ơng trình và đa CLR vào quản lí chơng trình, CLR đọc các thông tin metadata, điều khiển Loader nạp các th viện cần thiết vào bộ nhớ

 Hàm _CorExeMain đợc chèn vào điểm nhập của chơng trình.

 Bộ phận Loader nhảy vào điểm nhập chơng trình và gọi hàm

 Khi _CorExeMain thực thi, nó gọi chơng trình dịch JIT ra thực thi.

 JIT dịch mã IL sang mã máy và đa vào thực thi đồng thời đợc dự trữ ở bộ nhớ đệm để khi cần không phải dịch lại.

II Giới thiệu sơ bộ ngôn ngữ lập trình C#

Có thể coi ngôn ngữ lập trình C# là ngôn ngữ lập trình đơn giản vì nó chỉ có khoảng 80 từ khoá và khoảng 12 kiểu dữ liệu xây dựng sẵn ( built-in) tuy nhiên nó hỗ trợ tất cả các mô hình lập trình : lập trình cấu trúc, lập trình hớng đối tợng và lập trình hớng thành phần ( COM )

II.1 Lập trình hớng đối tợng trong C#

C# là ngôn ngữ hoàn toàn hớng đối tợng Tính chất hớng đối tợng có thể trình bày tóm tắt nh sau:

 “Tất cả đều là đối tợng” Trong C#, mọi thực thể đều đợc biểu diễn là đối tợng, đi cùng với nó là các thuộc tính, hành vi ( method ) của thực thể đó Nh vậy, một thuộc tính hay một method chắc chắn phải thuộc về một đối tợng nào đó.

 Một chơng trình ứng dụng bao gồm nhiều đối tợng Khi chúng muốn một đối tợng thực hiện một công việc hay đối tợng này muốn đối tợng kia thực hiện một công việc, chúng ta hay các đối tợng giao tiếp với nhau bằng cách gửi thông điệp Thông điệp có thể hiểu nh một lời gọi hàm gọi một method của đối tợng nào đó làm việc.

 Mỗi đối tợng có một vùng nhớ riêng.

 Mỗi đối tợng có một kiểu dữ liệu riêng, kiểu dữ liệu đợc định nghĩa bởi mét class ( líp ).

 Mỗi đối tợng có một giao diện để giao tiếp với các đối tợng khác và một phần dữ liệu đợc che giấu đối với các đối tợng khác.

Ngoài ra, C# cúng cho phép ngời lập trình thực hiện các hoạt động sử dụng lại dữ liệu nh kế thừa, đa hình thái và kết tập.

II.2 Những đặc điểm của ngôn ngữ C#

C# đợc xây dựng từ những ngôn ngữ tiền đặc biệt là C và C++ cho nên những đặc điểm ngôn ngữ của C# rất giống với ngôn ngữ C, C++ Trong phần này, chúng em sẽ trình bày một vài đặc điểm của C#.

Trong C# có các toán tử thông thờng sau:

 Các toán tử một toán hạng: ++,- -, !,~

 Các toán tử hai toán hạng: *, /, %, +, -

 Các toán tử gán: =, *=, /=, %=, +=, -=, =, &=, ^=, ! Các toán tử quan hệ: , =, is, as, ==, ! Các toán tử lô- gíc: &, ^, !, &, |,

 Các toán tử điều kiện: &&, ||, ?:

 Toán tử sizeof xác định kích thớc một kiểu dữ liệu.

Trong C# cũng cho phép chồng toán tử và định nghĩa các toán tử mới theo các qui tắc sau:

 Toán tử một toán hạng: type_of_x operation op(x)

 Toán tử hai toán hạng: type_of_x,y operation op(x,y)

Trong C# không cho phép định nghĩa lại toán tử gán.

II.2.2 Các kiểu dữ liệu:

C# hỗ trợ hai loại kiểu dữ liệu là kiểu tham trị và kiểu tham biến Kiểu tham trị bao gồm các kiểu đơn giản nh char, int, float Kiểu tham biến gồm các kiểu lớp, kiểu Interface, kiểu mảng hay nói cách khác tất cả các đối tợng đều là tham biễn.

Kiểu tham trị khác kiểu tham biến ở chỗ: những biến tham trị la trữ trực tiếp dữ liệu của nó, trái lại biến tham biến la trữ con trỏ trỏ tới đối tợng.

C# cung cấp một tập các kiểu đợc định nghĩa trớc hầu hết đã có trong C và C+ + Ngoài ra , C# lại đa thêm vào kiểu boolean, string giống nh trong Pascal.

C# cho phép chuyển kiểu giống nh C nà C++.

C# kế thừa hầu hết các câu lệnh từ C và C++, tuy nhiên cũng có một vài bổ xung và thay đổi đánh chú ý Chúng ta sẽ điểm qua các câu lệnh sau:

 Các lệnh đợc gán nhãn và lệnh goto: các lệnh đợc gắn nhẵn có một nhãn đứng đằng trớc Các lệnh goto sẽ nhảy đến các nhãn này và thực thi câu lệnh đợc gán nhãn

 Lẹnh if: lệnh if sẽ chọn một biểu thức để làm việc dựa trên giá trị một biểu thức lô- gic Một lệnh if có thể có thêm lệnh else để thực thi câu lệnh khác khi giá trị biểu thức là sai.

 Lệnh swich: lệnh switch thực thi một những lệnh phụ thuộc vào giá trị một biểu thức cho trớc.

 Các lệnh lặp: các lệnh lặp trong C# bao gồm các lệnh lặp while, do – while, for nh trong C

 Lệnh lặp foreach ( giống nh trong VB): một lệnh lặp foreach liệt kê các thành phần trong một tập hợp, thực thi một câu lệnh cho mỗi thành phần của tập hợp đó.

 Các lệnh throw, try, catch: các lệnh phục vụ cho quá trình quản lí lỗi trong thời gian chạy ( runtime – error ) gồm có phát ra một lỗi ( throw ), cặp lệnh try – catch đón nhận một lỗi và đa ra hành động xử lí lỗi

II.2.4 Cấu tạo của một chơng trình C#

Nếu nh trong C, đơn vị chơng trình lớn nhất là các hàm ( modul), trong Java và C++, đơn vị chơng trình lớn nhất là các lớp ( class) thì trong C#, đơn vị chơng trình lớn nhất là không gian tên (namespace) Một chơng trình C# chứa một hay nhiều không gian tên, trong đó một không gian tên chứa dữ liệu của chơng trình, các không gian tên còn lại là các không gian tên chứa phần dữ liệu ở các chơng trình khác đợc khai báo với từ khoá using sử dụng nh là phần th viện, ví dụ :

Namespace 1: namespace Microsoft.CSharp.Introduction

{ public string GetMessage() { return "Hello, world";

Namespace 2: using Microsoft.CSharp.Introduction; class Hello

Trong một namespace có thể lồng một hay nhiều namespace khác, ví dụ: namespace Microsoft

Dới namespace là các đơn vị chơng trình có thể coi là cùng cấp : lớp (class), cấu trúc (struct), giao diện (Interface).

 Lớp: lớp đợc dùng để định nghĩa những kiểu đối tợng mới Trong một lớp có thể có các hằng số, các trờng, phơng thức, thuộc tính, sự kiện, toán tử, hàm dựng, hàm huỷ Đối với mỗi thành phần của lớp thì có các thuéc tÝnh truy cËp sau:

- public: tất cả các đối tợng khác đều có thể truy cập đến các thành phần này.

- protected: chỉ những đối tợng kế thừa từ một đối tợng mới có thể truy cập vào thành phần protected của lớp cha.

Đồ họa trong C#

Giới thiệu về GDI+

GDI+ là một phân hệ của hệ điều hành MS Windows XP cung cấp những tính năng dựng hình 2D cơ bản như đồ họa vector, xử lý hình ảnh Đúng như tên của nó đã hàm ý, GDI+ là phiên bản cải tiến của GDI (thế hệ giao diện thiết bị đồ họa trước của Windows) Nó chịu trách nhiệm hiển thị và dựng hình trên màn hình, máy in. GDI+ được trang bị thêm nhiều tính năng mới và tối ưu các tính năng sẵn có.

GDI+ cho phép lập trình viên viết mã độc lập ứng dụng Điều này có nghĩa là lập trình viên chỉ việc viết mã để hiển thị thông tin mà không cần quan tâm đến thiết bị hiển thị cụ thể bên dưới Người lập trình chỉ việc gọi các hàm cung cấp bởi các lớp của GDI+ và các hàm này đến lượt chúng sẽ chịu trách nhiệm giao tiếp với một driver của thiết bị cụ thể GDI cách ly ứng dụng khỏi phần cứng và như vậy cho phép lập trình viên viết mã độc lập thiết bị.

Các lớp được quản lý của GDI+ là một phần của kiến trúc Microsoft NET,môi trường để xây dựng, phân phối và chạy các dịch vụ Web XML và các ứng dụng khác.

Kiến trúc của GDI+

Các dịch vụ của GDI+ được chia thành 3 lớp rộng sau:

Sau đây chúng ta sẽ xem xét lần lượt từng lớp này:

1 8 Đồ họa vector liên quan đến việc vẽ các thực thể đồ họa cơ sở như đường thẳng, đường cong hay khối hình được cho bởi một tập hợp các điểm trên một hệ tọa độ Ví dụ, một đường thẳng có thể được xác định bằng 2 điểm cuối của nó, 1 hình chữ nhật có thể được xác định bằng cách chỉ ra 1 điểm xác định đỉnh trái trên và 1 cặp số xác định chiều cao và chiều rộng của nó Một đồ thị đơn giản có thể được xác định bởi 1 mảng các điểm được nối với nhau bởi đường thẳng 1 đường Bézier spline là một đường cong tinh vi được xác định bởi 4 điểm điều khiển.

GDI+ cung cấp các lớp và cấu trúc lưu trữ thông tin về các thực thể cơ sở, các lớp lưu trữ thông tin về cách thức mà các thực thể này được dựng và các lớp chịu trách nhiệm hiển thị hình ảnh lên thiết bị Ví dụ, cấu trúc Rectangle lưu trữ thông tin về vị trí và kích cỡ của hình chữ nhật; lớp Pen lưu trữ thông tin về màu sắc, độ rộng đường thẳng và kiểu đường thẳng; Còn lớp Graphics có các phương thức cho dựng đường thẳng, hình chữ nhật, đồ thị và các hình hình học khác Còn có thêm vài lớp Brush lưu trữ thông tin về cách thức mà các hình này được tô màu.

Ta có thể ghi lại hình ảnh vector (thực chất là một chuỗi các lệnh dựng hình) trong một metafile GDI+ cung cấp lớp Metafile để ghi lại, hiển thị và lưu các metafile Các lớp MetafileHeader và MetaHeader cho phép ta lưu trữ thông tin trong phần header của metafile.

Có một số loại hình ảnh có thể rất khó hoặc không thể được hiển thị với các kỹ thuật của đồ họa vector Ví dụ, hình ảnh trên thanh công cụ hoặc các hình icon có thể khó mô tả bởi một tập các đường thẳng và đường cong Một bức ảnh độ phân giải cao thậm chí còn khó tạo hơn với các ký thuật đồ họa vector Các hình ảnh dạng này được lưu trữ dưới dạng các ảnh bitmap (một dãy các số biểu diễn màu sắc của từng điểm trên màn hình GDI+ cung cấp lớp Bitmap để xử lý, hiển thị và lưu các ảnh bitmap.

II.3 In ấn v hiển thị font chữ à hiển thị font chữ

Phần in ấn và hiển thị font chữ chịu trách nhiệm hiển thị văn bản bằng nhiều loại font, cỡ chữ và kiều khác nhau GDI+ cung cấp một số lượng rất ấn tượng hỗ trợ cho các nhiệm vụ phức tạp này Một trong những các đặc tính mới của GDI+ là chống răng cưa, cho phép hiển thị chữ viết mịn hơn trên các màn hình CRT phẳng và màn hình LCD.

Kiến trúc lớp của GDI+

Giao diện lớp được quản lý của GDI+ chứa 60 lớp, 50 kiểu liệt kê, 8 kiểu cấu trúc Lớp Graphics là phần trung tâm của các chức năng của GDI+, nó chịu trách nhiệm dựng đường thẳng, đường cong, hình ảnh và văn bản.

Rất nhiều lớp khác hoạt động chung với lớp Graphics Ví dụ, phương thức Graphics.DrawLine sử dụng một đối tượng Pen lưu trữ các thông tin về màu sắc, độ rộng, kiểu mẫu của đường thẳng cần vẽ Phương thức Graphics.FillRectangle có thể nhận 1 con trỏ đến một đối tượng LinearGradientBrush, nó chịu trách nhiệm tô màu cho một hình chữ nhật có đổi màu theo 1 bảng màu Gradient Các đối tượng Font và StringFormat tác động lên cách thức mà đối tượng Graphics sẽ hiển thị văn bản Một đối tượng Matrix lưu trữ và thực hiện các thao tác chuyển đổi tọa độ trong đối tượng Graphics được dùng để thực hiện các phép quay, tỉ lệ và lật ảnh.

GDI+ cung cấp một vài cấu trúc (ví dụ như Rectangle, Point hay Size) để tổ chức dữ liệu đồ họa Một vài lớp khác cũng phục vụ chủ yếu cho mục đích lưu trữ các cấu trúc dữ liệu Ví dụ lớp BitmapData hỗ trợ lớp Bitmap, lớp PathData hỗ trợ cho lớp GraphicsPath.

GDI+ định nghĩa một vài kiểu liệt kê Chúng là các tập hợp của các hằng có liên quan Ví dụ, tập liệt kê LineJoin bao gồm các thành phần Bevel, Milter vàRound xác định các kiểu nối 2 đoạn thẳng.

Mét sè ®iÓm míi trong GDI+

GDI+ mở rộng tính năng của GDI bằng cách thêm các bút vẽ gradient để tô màu hình vẽ, đường thẳng và miền hình vẽ Ta có thể dùng một bút vẽ Gradient tuyến tính để phủ màu một hình vẽ với màu sắc thay đổi dần dần qua từng vùng trong hình vẽ này Hình vẽ sau minh họa điều này.

Hình 3 Tô màu bằng bút vẽ Gradient tuyến tính

Khi ta phủ một hình vẽ với một bút vẽ gradient có rất nhiều tùy chọn quy định cách thức màu sắc sẽ thay đổi từ vùng này đến vùng khác của hình Một lựa chọn là quy định màu ở trung tâm và màu ở biên, như vậy các điểm ảnh sẽ thay đổi màu sắc một cách từ từ tính từ trung tâm ra biên Hình sau minh họa của một ảnh được tạo ra từ một cặp đường Bézier được tô bởi một bút phủ Gradient.

Hình 4 Đờng Bézier đợc tô bởi bút phủ Gradient

2 §êng cong Spline

GDI+ hỗ trợ đường cong Spline Một đường cong Spline là một chuỗi các đường cong độc lập được hợp lại để tạo thành một đường cong lớn hơn Đường spline được xác định bởi một mảng các điểm và đi qua tất cả các điểm trong mảng đó Một đường spline là 1 đường cong trơn đi qua các mỗi điểm trong mảng Hình sau cho thấy 2 đồ thị: 1 đường được tạo bởi 1 đường cong spline và đường còn lại được tạo bằng cách nối bằng các đoạn thẳng.

IV.3 Đối tợng đồ họa độc lập

Trong GDI, một đồ thị thuộc về 1 ngữ cảnh thiết bị, và đồ thị bị hủy khi mà nó được vẽ ra Trong GDI+, chức năng vẽ được thực hiện bởi 1 đối tượng Graphics và ta có thể tạo và duy trì một vài đối tượng GraphicsPath riêng rẽ với đối tượng Graphics Một đối tượng GraphicsPath không bị hủy bởi hành động vẽ, vì vậy ta có thể dùng một đối tương GraphicsPath để vẽ nhiều lần.

IV.4 Chức năng chuyển đổi v đối t à hiển thị font chữ ợng ma trận

GDI+ cung cấp đối tượng Matrix, một công cụ mạnh để thực hiện các phép biến đổi như quay, dịch một cách dễ dàng và mềm dẻo Một đối tượng ma trận hoạt động cùng với đối tượng sẽ chịu biến đổi Ví dụ đối tượng GraphicsPath có phương thức Tranform nhận vào đối số là một ma trận 1 ma trận 3x3 có thể được dùng để thực hiên một phép biến đổi hay một dãy các phép biến đổi Hình sau minh họa 1 đồ thị trước và sau khi thực hiện một dãy các chuyển đổi ( đầu tiên là phép tỉ lệ, sau là phép quay).

Hình 5 Chuyển đổi đồ thị

IV.5 Vùng ảnh co giãn đợc

GDI+ mở rộng rất nhiều khả năng hỗ trợ vùng ảnh của nó Trong GDI, vùng được lưu trong hệ tọa độ thiết bị và phép biến đổi duy nhất có thể áp dụng với 1 vùng ảnh là phép dịch chuyển GDI+ lưu trữ vùng ảnh trong hệ tọa độ chung và cho phép vùng này chịu bất kỳ phép chuyển đổi nào lưu trữ được trong 1 ma trận chuyển đổi Hình sau minh họa 1 vùng ảnh trước và sau 1 chuỗi 3 phép chuyển đổi: tỉ lệ, quay và dịch chuyển.

Hình 6 Co giãn vùng ảnh

Trong hình trên ta có thể thấy vùng chưa được chuyển đổi (được phủ bởi màu đỏ) qua phần đã được chuyển đổi (phủ bởi các đường sọc màu xanh) Điều này được thực hiện thông qua kỹ thuật đổ bóng Alpha được hỗ trợ bởi GDI+ Với kỹ thuật đổ bóng Alpha ta có thể quy định độ trong suốt của 1 màu Khi một màu phối hợp với 1 màu nền, nếu màu càng trong suốt ta nhìn thấy màu nền càng rõ Hình sau minh họa các mức độ trong suốt.

Hình 7 Các mức độ trong suốt của màu nền

Thay đổi trong mô hình lập trình

V.1 Ngữ cảnh thiết bị, Handles v các đối t à hiển thị font chữ ợng đồ họa

Nếu đã viết chương trình dùng GDI, lập trình viên chắc hẳn đã quen với khái niệm ngữ cảnh thiết bị Một ngữ cảnh thiết bị là một cấu trúc của Windows lưu trữ khả năng của một thiết bị hiển thị cụ thể và các thuộc tính xác định cách thức mà các đối tượng sẽ được vẽ lên thiết bị đó Một ngữ cảnh thiết bị cho 1 màn hình video cũng được liên kết với 1 cửa sổ trong màn hình hiển thị Đầu tiên ta sẽ nhận được một handle trỏ đến 1 ngữ cảnh thiết bị (HDC) Ta sẽ chuyển handle này cho hàm GDI thực hiện công việc vẽ.

Với GDI+ ta không phải lo về việc sử dụng các handle cũng như ngữ cảnh thiết bị Đơn giản là ta chỉ phải tạo 1 đối tượng Graphics và gọi các phương thức của nó với 1 phong cách hướng đối tượng quen thuộc Đối tượng Graphics là trung tâm của GDI+ cũng như ngữ cảnh thiết bị là trung tâm của GDI Ngữ cảnh thiết bị và đối tượng Graphics có vai trò tương tự nhau nhưng có một số khác biệt cơ bản giữa mô

2 2 hình lập trình dựa trên các handle (hay con trỏ) trong GDI và mô hình lập trình hướng đối tượng trong GDI+. Đối tượng Graphics, giống như ngữ cảnh thiết bị, được liên kết với một cửa sổ cụ thể trên màn hình và có các thuộc tính quy định cách thức vẽ các đối tượng Tuy nhiên đối tượng Graphics lại không bị trói chặt với một đối tượng bút vẽ, bút tô, đồ thị, hình ảnh hay font chữ như một ngữ cảnh thiết bị Ví dụ, trước khi ta dùng một ngữ cảnh thiết bị để vẽ một đường thẳng ta phải gọi phương thức SelectObject để liên kết một đối tượng bút vẽ với 1 ngữ cảnh thiết bị Điều này thường được biết đến như việc chọn một bút vẽ vào ngữ cảnh thiết bị Mọi đường thẳng được vẽ trong ngữ cảnh thiết bị sẽ dùng bút đã chọn Với GDI+, ta chuyển đối tượng bút vẽ Pen như một tham số cho phương thức vẽ đường thẳng DrawLine của lớp Graphics Ta có thể dùng các bút vẽ khác nhau trong một dãy các thao tác vẽ đường thẳng mà không cần phải liên kết một đối tượng bút vẽ với 1 đối tượng Graphics.

V.2 Bút vẽ, bút phủ, đồ họa, hình ảnh v Font chữ à hiển thị font chữ

Các đối tượng Bút vẽ, bút phủ, đồ họa, hình ảnh và Font chữ có thể được tạo ra và lưu trữ riêng biệt với đối tượng Graphics Rất nhiều phương thức vẽ của lớpGraphics nhận cá đối tượng này làm các tham số Đây là điều trái ngược với GDI khi ta phải chọn các đối tượng này vừo ngữ cảnh thiết bị và chuyển handle của ngữ cảnh thiết bị như một đối số đến hàm vẽ.

Giới thiệu các đối tợng đồ họa cơ bản trong GDI+

GDI+ vẽ các đường thẳng, hình chữ nhật và các hình khác trên 1 hệ trục tọa độ Ta có thể chọn rất nhiều hệ tọa độ nhưng hệ tọa độ mặc định có điểm gốc là góc trái trên của màn hình Đơn vị đo của hệ trục tọa độ mặc định là pixel.

Hình 8 Hệ trục toạ độ của GDI+ Đồ họa vector của GDI+ hỗ trợ một số lớp cơ bản rất hữu ích sau:

Lớp Graphics trong GDI+ cung cấp các phương thức để vẽ các đối tượng trên

DrawLine, DrawRectangle, DrawEllipse, DrawPolygon, DrawArc, DrawCurve và DrawBezier DrawBezier.

Mỗi phương thức trên đều được overload để nhận một vài danh sách tham số Tất cả các phương thức đều làm việc kết hợp với một đối tượng bút vẽ Pen Để vẽ bất kỳ thứ gì ta phải tạo ít nhất 2 đối tượng: một đối tượng Graphics và một đối tượng Pen. Đối tượng Pen lưu trữ thông tin về thuộc tính như độ rộng đường và màu sắc cho hình được vẽ.

VI.2 Hình ảnh v Metafile à hiển thị font chữ

Lớp Image là một lớp cơ sở trừu tượng cung cấp các phương thức làm việc với các ảnh raster (dạng ảnh bitmap) và các ảnh vector Các lớp Bitmap và Metafile đều kế thừa lớp Image Lớp Bitmap mở rộng khả năng của lớp Image bằng cách cung cấp thêm các phương thức cho tải, lưu giữ và xử lý các ảnh raster Lớp Metafile mở rộng thêm khả năng ghi lại các hình ảnh vector.

GDI+ cung cấp lớp Metafile để ta có thể ghi lại và hiển thị các metafile Một metafile còn gọi là một hình ảnh vector là một hình ảnh được lưu lại như một chuỗi các lệnh vẽ Những lệnh vẽ được lưu trong 1 đối tượng Metafile có thể được lưu trong bộ nhớ hay lưu trong 1 file hoặc một đối tượng stream.

GDI+ có thể hiển thị các metafile được lưu dưới các định dạng sau:

GDI+ có thể ghi lại được metafile trong định dạng EMF và EMF+ nhưng không trong định dạng WMF EMF là một phần mở rộng của GDI+ cho phép GDI+ ghi và lưu lại Chỉ có 2 biến đổi với định dạng EMF: EMF+ đơn và EMF+ kép. EMF+ đơn chỉ chứa các bản ghi GDI+ Các metafile như vậy có thể được hiển thị bởi GDI+ nhưng không phải GDI EMF+ kép có chứa cả bản ghi GDI+ và GDI Mỗi bản ghi GDI+ lưu trong 1 EMF+ metafile là một cặp với 1 bản ghi thay thế của GDI. Mỗi metafile như vậy có thể được hiển thị bởi GDI+ hay GDI.

Ví dụ sau hiển thị 1 metafile đã được lưu trước đó dưới dạng 1 file 1 Metafile được hiển thị với góc trên tại điểm (100,100). public void Example_DisplayMetafile(PaintEventArgs e)

Metafile myMetafile = new Metafile("SampleMetafile.emf"); myGraphics.DrawImage(myMetafile, 100, 100);

VI.3 Các loại hệ tọa độ

GDI+ dùng 3 loại hệ tọa độ không gian: thế giới thực, trang và thiết bị Khi ta có một lời gọi đến hàm myGraphics.DrawLine(myPen, 0, 0, 160, 80) điểm mà ta sẽ truyền cho phương thức DrawLine – (0,0) và (160,80) là ở trong hệ tọa độ thực Trước khi GDI+ có thể vẽ đường thẳng lên màn hình, hệ tọa độ trải qua một dãy các biến đổi 1 phép chuyển đổi sẽ chuyểntọa độ thực về tọa độ trang và một phép chuyển đổi khác chuyển hệ tọa độ trang thành hệ tọa độ thiết bị.

Chẳng hạn khi ta muốn làm việc với 1 hệ thống tọa độ có điểm 0 nằm ở giữa vùng client thay vì là ở góc trái trên, ví dụ bắt đầu từ pixel 100 từ cạnh trái của vùng client và 50 pixel từ đỉnh của vùng client Hình sau minh họa hệ tọa độ như vậy và kết quả khi gọi hàm myGraphics.DrawLine(myPen, 0, 0, 160, 80):

Hình 9 Dịch chuyển hệ toạ độ

Phép chuyển đổi thực hiện việc ánh xạ hệ tọa độ thực vào hệ tọa độ trang được gọi là phép chuyển đổi hệ tọa độ thực và được lưu trong thuộc tính Transform của lớp Graphics Phép chuyển đổi thực hiện việc ánh xạ tọa độ trang vào hệ tọa độ thiết bị được gọi là một phép chuyển đổi trang Lớp Graphics cung cấp các thuộc tính PageUnit và PageScale để xử lý các chuyển đổi trang Lớp này cũng cung cấp các thuộc tính DpiX và DpiY để xác định độ phân giải điểm ảnh dọc và ngang của thiết bị hiển thị.

VI.4 Các phép chuyển đổi

Một phép chuyển đổi tổng thể là một phép chuyển đổi áp dụng lên tất cả các đối tượng được vẽ bởi 1 đối tượng Graphics Để thực hiện một phép chuyển đổi ta tạo 1 đối tượng Graphics, thao tác với thuộc tính Transform của nó Thuộc tính Transform là một đối tượng ma trận, do vậy nó có thể lưu giữ một số lượng bất kỳ dãy các phép biến đổi Affine Phép chuyển đổi được lưu trong thuộc tính Transform được gọi là phép chuyển đổi hệ tọa độ thế giới thực Lớp Graphics cung cấp một vài phương thức để tổng hợp một phép biến đổi phức tạp: MultiplyTransform,

RotateTransform, ScaleTransform, và TranslateTransform Sau đây là một ví dụ về phép chuyển đổi này: myGraphics.DrawEllipse(myPen, 0, 0, 100, 50); myGraphics.ScaleTransform(1, 0.5f); myGraphics.TranslateTransform(50, 0, MatrixOrder.Append); myGraphics.RotateTransform(30, MatrixOrder.Append); myGraphics.DrawEllipse(myPen, 0, 0, 100, 50);

Một phép chuyển đổi cục bộ là một phép biến đổi áp dụng cho một đối tượng cụ thể Đối tượng Graphics cho phép tạo một ảnh đồ họa và áp dụng các phép chuyển đổi lên đó Ví dụ:

Matrix myMatrix = new Matrix(); myMatrix.Rotate(45); myGraphicsPath.Transform(myMatrix); myGraphics.DrawRectangle(myPen, 10, 10, 100, 50); myGraphics.DrawPath(myPen, myGraphicsPath);

Đa luồng trong C#

Khái niệm đa luồng

Trớc khi hiểu hoàn toàn về luồng, chúng ta sẽ tìm hiểu thế nào hệ điều hành Windows hoạt động nh thế nào trong chế độ đa nhiệm:

Trớc hết ta có thể nói Windows là một hệ thống đa nhiệm Trong chế độ đa nhiệm, hệ điều hành sẽ phân bố thời gian giữa các tiến trình và quyết định tiến trình nào nên đợc chạy kế tiếp khi tiến trình hiện hành kết thúc thời gian đợc chia sẻ trên vi xử lý Do đó hệ điều hành ngắt tiến trình đều đặn giữa các khoảng thời gian để đa tiến trình kế tiếp trong hàng đợi vào thực hiện vì vậy không có tiến trình nào có độc quyền chiếm CPU tại bất cứ thời điểm của thời gian Số lợng thời gian đa tới mỗi tiến trình phụ thuộc vào bộ vi xử lý và hệ điều hành Thời gian xử lý cho mỗi tiến trình rất nhỏ điều này đa ra cảm tởng rằng một tập hợp các tiến trình chạy đồng thời nhng thực tế mỗi tiến trình chạy trong môt số miligiây nào đó sau đó tới tiến trình khác và sự chuyển đổi này xảy ra rất nhanh Đây là phơng cách mà các Windows 95/98/NT hay ngay cả Unix dùng để quản lý các tiến trình Tuy nhiên ở các hệ điều hành ban đầu nh Win 3.x và DOS thì nó lại quản lý ở chế độ đơn nhiệm (monotasking) Trong chế độ này mỗi tiến trình có thể điều khiển CPU trong bao lâu mà nó cần, với cách thực hiện này một tiến trình ngăn chặn các tiến trình khác đợc xử lí đồng thời.

Không gian bộ nhớ, trong đó một ứng dụng đợc thực hiện đợc gọi là tiến trình (process) Trong phạm vi một tiến trình thờng có nhiều công việc cần đợc thực hiện. Quá trình thực hiện một công việc đợc gọi là một luồng (tiểu trình) Các công việc trong một tiến trình có thể thực hiện tuần tự, lúc này chỉ có một luồng chạy thực hiện các công việc, ta gọi đây là chế độ đơn luồng Các công việc của tiến trình cũng có thể thực hiện đồng thời, lúc này có nhiều luồng thực hiện nhiều công việc.

Nh vậy ta gặp lại hình ảnh đa nhiệm trong đa luồng, chúng có thể phân biệt chúng đơn giản nh sau:

 Đa nhiệm: bao gồm các ứng dụng khác nhau chạy đồng thời dới sừ điều khiển của hệ điều hành, chúng chia sẻ CPU và bộ nhớ.

 Đa luồng: chỉ tồn tại trong một ứng dụng, bao gồm các công việc của một ứng dụng đợc chạy đồng thời, chúng chia sẻ tài nguyên CPU và bộ nhớ mà hệ điều hành phân cho ứng dụng đó, chúng đợc điều khiển bởi một mô đun trong ứng dụng

Trong một ứng dụng Window có các loại luồng sau:

 Luồng đơn ( Single Threading ): chỉ có một luồng trong ứng dụng và nó phải làm tất cả các công việc Luồng đó có tất cả các không gian phân phối cho process Lúc này ta có thể đồng nhất luồng với ứng dụng.

 Luồng Apartment ( ở đây lấy hình ảnh ứng dụng là khu nhà, mỗi luồng là mộ căn hộ): có nhiều luồng trong ứng dụng ứng dụng sẽ định khi nào và bao lâu cho một luồng nên thực hiện Mỗi luồng có gán cho một không gian riêng trong phạm vi không gian cho ứng dụng và các luồng khác không chia sẻ các nguồn tài nguyên đó.

 Luồng tự do ( Free Threading ): có nhiều luồng trong một ứng dụng và những luồng này chia sẻ nguồn tài nguyên chung Các luồng khác nhau có thể gọi cùng một phơng thức và thuộc tính tại một thời điểm Mô hình Apartment thì hiệu quả hơn mô hình single threading bởi vì công việc đ- ợc phân chia giữa nhiều đối tợng trong khi mô hình free thì nhanh nhất và hữu hiệu nhất Nhng chế độ free ẩn chứa nhiều rủi ro bởi vì sự chia sẻ tài nguyên giữa nhiều đối tợng, ngời lập trình cần phải chú ý nhiều đến sự đồng bộ và tránh các xung đột xảy ra.

Đa luồng trong C#

Trong phần trên ta thấy đợc phần nào hệ điều hành quản lý các ứng dụng cùng chạy đồng thời.Từ thực tế ta cũng có những ứng dụng tính toán phức tạp cần nhiều thời gian thực hiện hay các ứng dụng cần xử lý song song (paralell), hay ứng dụng cần lấy dữ liệu từ xa đồng thời hiển thị dữ liệu trên màn hình cho ta thấy đa luồng đóng vai trò quan trọng trong cuộc sống của chúng ta Tuy nhiên không phải hầu hết các ngôn ngữ lập trình đều cho phép lập trình viên chỉ định các hành động diễn ra đồng thời Thay vào đó ngôn ngữ lập trình cung cấp cho chúng ta một tập cấu trúc đơn giản để cho một chơng trình hoạt động tại một thời điểm và chỉ tiếp tục hành động tiếp theo khi hành động thứ nhất đã kết thúc Kiểu hoạt động đồng thời mà các máy tính ngày nay thờng cài đặt là tính năng hoạt động đồng thời nguyên thủy của hệ điều hành vốn chỉ sử dụng bởi các lập trình viên hệ thống cực kỳ kinh nghiệm Ngôn ngữ C# cùng với các ngôn ngữ khác trong bộ NET đã biến các tính năng nguyên thủy đồng thời trở nên sẵn sàng cho ngời lập trình xây dựng các ứng dụng cá nhân.Lập trình viên C# có thể xây dựng ứng dụng có nhiều luồng thi hành mà mỗi luồng chỉ định rõ một phần công việc trong số nhiều phần việc của một chơng trình và có thể thi hành đồng thời với các luồng khác.Một ứng dụng cụ thể của kỹ thuật đa luồng là khả năng tự gom rác của C# trong đó C# cung cấp một luồng gom rác tự động chạy thu hồi phần bộ nhớ đã đợc phân phối cấp phát mà chơng trình chính không dùng nữa.Tuy nhiên bên cạnh tạo ra các ra các ứng dụng đa luồng có thể cải thiện đợc hiệu suất của ứng dụng tuy nhiên việc thêm nhiều tiểu trình có thể làm tăng độ phức tạp của ứng dụng của chúng ta cũng nh làm làm chậm việc tính toán (do vi xử lý phải chuyển đổi liên tục từ luồng này sang thực hiện luồng tiếp theo sau đó lại quay lại thực hiện luồng đó) và làm cho việc bảo trì và gỡ rối tăng lên

II.1 Cấu trúc các lớp điều khiển luồng của C#

Trong ngôn ngữ lập trình C# không gian tên System.Threading cung cấp các lớp, các giao diện cho việc lập trình đa luồng Trong không gian tên này bao gồm lớpThreadPool quản lý các nhóm các luồng, lớp Timer cho phép một đại diện chuyển giao đợc gọi sau một lợng thời gian chỉ định và lớp Mutex cho sự đồng bộ giữa các

2 8 luồng với nhau Ngoài ra System.Threading cũng cung cấp các lớp cho việc định mức u tiên của các luồng, chờ đợi thông báo…

Sau đây ta có một sơ đồ cấu trúc của không gian tên System.Threading:

AutoResetEvent Thông báo một or nhiều luồng đang chờ đợi cho một sự kiện đã xảy ra và tự động khởi động.

InterLocked Cung cấp hoạt động tối thiểu cho các biến đợc chia sẻ bởi nhiều luồng ManualResetEvent Xảy ra khi thông báo một hoặc nhiều luồng có một sự kiện vừa xảy ra Monitor Cung cấp một cơ chế cái đồng bộ hóa truy nhập các đối tợng RegisteredWaitHandle Diễn tả một đăng ký cái mà đã đợc đăng ký khi goi đối tợng

Ngoại lệ đợc đa ra khi một phơng thức đồng bộ hóa đợc đa ra từ một khối mã đóng không đồng bộ hóa Thread Tạo và điều khiển luồng, và nhận các trạng thái của nó ThreadAbortException Một ngoại lệ cái mà đợc đa ra khi một lời gọi đợc chế tới phơng thức Abort ThreadExceptionEventArgs Cung cấp dữ liệu cho một sự kiện

ThreadException ThreadInterruptedException Một ngoại lệ đợc đa ra khi một luồng bị ngắt trong khi nó ở trong trạng thái chờ đợi.

ThreadPool Cung cấp một sự dùng chung của các luồng có thể sử dụng xử lý không đồng bộ vào ra, chờ đợi ,xử lý thời gian, xử lý chuyển công việc.

ThreadStateException Ngoại lệ đợc đa ra khi luồng trong một trạng thái không hợp cho lời gọi phơng thức.

Timeout Chứa đựng một hằng chỉ định cho một khoảng thời gian nhất định.

Timer Chỉ định một cơ chế cho thực hiện một phơng thức giữa khoảng thời gian chỉ định,

LockCookie Định nghĩa một lock thực hiện các văn phạm singer_writer hoặc multiple_writer NativeOverlapped Cung cấp một cấu trúc rõ ràng cái mà hiện từ code không quản lý và cái đó có câứ trúc giống cấu trúc Win32 overlapped với các trờng dự trữ thêm vào tai cuối.

ThreadStart Mô tả phơng thức cái mà bắt đầu với Thread class ThreadExceptionEventHandl er

Mô tả phơng thức cái mà điều khiển sự kiện ThreadException của ứng dụng.

IOCompletionCallback Nhận mã lỗi ,số các bytes ,và các giá trị trùng khi hoạt động vào ra hoàn thành trên threadpool TimerCallback Mô tả phơng thức cái mà điều khiển t/thái của

ApartmentState Chỉ định trạng apartment của một Thread

ThreadPriority Chỉ định thời gian biểu cho Thread

ThreadState Chỉ định trạng thái của Thread

II.2 Tổng quát các phơng thức của lớp Thread

II.2.1 Tạo luồng ( create thread ) Để tạo một luồng với lớp Thread, trớc hết ta cần có một phơng thức làm việc nh một đại diện chuyển giao luồng Trong NET dùng đại diện chuyển giao để định nghĩa một phơng thức mà luồng mới sẽ dùng Giả sử rằng chúng ta có một phơng thức MyThread, thì phơng thức này đóng vai trò đại diện, định nghĩa cho luồng Sau đó tạo một đối tợng của lớp Thread và constructor cho một Thread sẽ là một thông số cho đại diện ThreadStart Nh vậy đại diện ThreadState định nghĩa các phơng thức mà luồng mới tạo thành sẽ thi hành.

ThreadStart mt=new ThreadStart(MyThread);

//Doan tren tao ra mot dai dien chuyen giao

//Tao mot đối tợng của lớp Thread lây tham sô là đai diện chuyển giao. Thread myluong=new Thread(mt);

Tuy nhiên đến bớc trên luồng vẫn cha thực hiện đợc và vẫn ở trạng thái Unstarted và khi ta gọi phơng thức Start của lớp Thread thì hệ điều hành sẽ thay đổi trạng thái của luồng tới trạng thái ThreadState.Running Khi Start đợc gọi thì thực hiên dòng đầu tiên của phơng thức ( ở vi dụ này MyThread ) tham chiếu bởi đại diện chuyển giao Delegate Khi phơng thức Start đợc gọi thì nó có thể gây ra một số ngoại lệ mà ta cần chú ý :

ThreadStateException Luông đã bắt rồi.

SecurityException Lời gọi không có cho phép thực hiện OutOfMemoryExceptio n Không đủ bộ nhớ thực hiện luồng

NullReferenceException Lời gọi tham chiếu một luồng mà null ở đây ta cũng chú ý là một khi luồng đã ngắt thì không thể có lời gọi Start lần nữa Khi phong thức Start khởi đầu luồng này, phơng thức Start sẽ trả điều khiển cho luồng gọi ngay lập tức Khi đó luồng gọi sẽ thi hành đồng thời luồng vừa phát động. Để biết đợc trạng thái của một luồng ta có thể sử dụng thuộc tính

Thread.ThreadSate hay thuéc tÝnh Thread.isAlive public ThreadState ThreadState {get;} (**) public bool IsAlive {get;}) (*)

(*) - Thuộc tính này có giá trị là true khi mà luồng đã đợc gọi và cha chết ( tức là ph- ơng thức stop của nó cha đợc gọi và phơng thức kiểm soát run của nó cha hoàn tất nhiệm vụ) ngợc lại nó có giá trị false khi luồng đã kết thúc

(**)- Giá trị của thuộc tính này trả về là trạng thái hiện hành của luồn và khởi đầu với giá trị unstarted.

Khi tạo một luồng ta có thể gán tên cho luồng đó để nhấn dạng tên luồng đang chạy bằng cách sử dụng thuộc tính Thread.Name để gán thuộc tên cho luồng Điều cần lu ý khi sử dụng thuộc tính này là đây là thuộc tính chỉ ghi và một luồng chỉ đợc dặt tên cho một lần duy nhất mà thôi nếu không sẽ gây ra một lỗi ngoại lệ InvalidOperationException (thiết đặt một yêu cầu mà tên đó đã đợc đặt rồi).

II.2.2 Nhập luồng ( join thread )

Khi ta cần dừng xử lý một luồng và chờ đợi cho luồng thứ hai kết thúc gọi là luồng thứ nhất gia nhập luồng thứ hai hay nói cách khác là gắn đầu luồng một vào đuôi luồng thứ hai C# cung cấp cho chúng ta ba phơng thức : public void Join() ;(*) public bool Join(int);(**) public bool Join(TimeSpan);(***)

(*) Khi dùng phơng thức này thì nó sẽ đóng luồng cho đến khi luồng thứ hai bị ngắt Tuy nhiên sự chờ đợi không hạn định này có thể gây ra vấn đề nghiêm trọng đó là bế tắc hoàn toàn (deadlock) và trì hoãn vô hạn (infinitive postponement) Phơng thức này tung ra hai lỗi ngoại lệ là ThreadSateException khi mà lời gọi cố gắng gia nhập luồng trong khi đang ở trạng thai ThreadState.Unstarted và ngoại lệ thứ hai xảy ra là ThreadInterruptException tức là luồng bị ngắt trong khi đang chờ đợi.

(**) Khi dùng phơng thức này thì luồng sẽ bị đóng cho đến khi luồng thứ hai ngắt hay thời gian chỉ định hết Phơng thức này trả lại giá trị true nếu luồng hai kết thúc hoặc trả lại false khi hết thời gian mà luồng hai cha kết thúc Phơng thức này cũng sinh ra hai ngoai lệ là ThreadSateException tức luồng cha bắt đầu hoặc do thời gian là âm ArgumentOutOfRangeException.

XML và C#

Lịch sử các ngôn ngữ đánh dấu

I.1 Khái niệm đánh dấu (markup) “ ”

Nh chúng ta đã biết, khái niệm “đánh dấu” ở đây ám chỉ việc gán thẻ (tagging) cho các tài liệu điện tử vì hai mục đích: định dạng văn bản hoặc tạo nên các cấu trúc theo một ý nghĩa nào đó cho một tài liệu để có thể kết xuất hoặc trao đổi, ví dụ nh kết xuất ra máy in hoặc tải lên World Wide Web.

Nếu chúng ta đã từng sử dụng một trình soạn thảo HTML ví dụ nh Microsoft FrontPage hay chơng trình soạn thảo ví dụ nh MicrosoftWord thì chắc hẳn chúng ta đã quen với khái niệm thay đổi định dạng văn bản trong một tài liệu Vậy các chơng trình đó thực hiện thao tác này ra sao? Thực ra các trình soạn thảo đó đã dùng các kí tự “đánh dấu” để định dạng văn bản Ta xét một ví dụ sau đơn giản Giả sử ta tạo một văn bản theo định dạng rtf(rich text format) trong trình soạn thảo WordPad:

Hình 12 Minh hoạ soạn thảo trong WordPad

Ta có thể xem code của văn bản trên (ví dụ trong NodePad):

Hình 13 Mã của văn bản đọc bằng NotePad

Nh ta thấy phần code của văn bản khác hơn nhiều so với phần hiển thị của nó Nh vậy trình soạn thảo (ở đây là WordPad) xử lí các thẻ đánh dấu trong code để hiển thị cho ngời sử dụng Ví dụ nh thẻ \rtf1 báo cho trình soạn thảo biết đây là văn bản theo định dạng rtf, thẻ \par bắt đầu một dòng mới Trình soạn thảo chỉ có nhiệm vụ đọc các thẻ gán và diễn dịch ý nghĩa các thẻ sau đó hiển thị cho ngời sử dông.

Tuy nhiên nếu ta tạo một văn bản nh trên theo định dạng Word Phần code của văn bản có dạng sau :

Hình 14 Mã của văn bản Word đọc bằng NotePad

Trình soạn thảo Word đã thêm một số thành phần vào các thẻ định dạng rtf và lu toàn bộ tài liệu dới dạng file nhị phân và ta không thể đọc đợc dới dạng file văn bản Ta còn gọi đây là định dạng theo kiểu đóng tức là các hãng khác nhau có thể đ a

4 0 ra các định dạng khác nhau cho file tập tin nhị phân và các trình soạn thảo riêng biệt phải hiểu rõ ý nghĩa của luồng các bit vào từ đó phiên dịch ra kết quả cho ngời sử dụng Còn định dạng theo kiểu mở tức là các file nhị phân đó đã đợc chuẩn hoá Ví dụ nh khi trình soạn thảo đọc đợc các bit 1100001 thì nó sẽ diễn giải thành số ‘97’ và tập tin nhị phân đợc chuẩn hoá còn đợc gọi là tập tin văn bản hay là mang tính chất mở.

Bên cạnh việc dùng để định dạng văn bản, khái niệm “đánh dấu” còn đợc sử dụng để tạo ra các cấu trúc hay ngữ cảnh của các thành phần.Ví dụ nh ta có thể xác định một tài liệu chỉ chứa các thành phần nh tên, tuổi, ngày sinh Ngoài ra ta còn có thể định dạng tài liệu nếu không chứa thành phần tên thì không chứa các thành phần nh tuổi, ngày sinh Mặt khác kiểu của các thành phần cũng đợc xác định nh thành phần tên ở dới dạng văn bản, thành phần ngày sinh dới dạng ngày tháng và thành phần tuổi dới dạng số Nh vậy ở đây khái niệm “đánh dấu” đợc dùng để thiết lập cấu trúc của tài liệu và ngữ nghĩa của các thành phần Ta tạo ra một tài liệu có nội dung nh ví dụ trên bằng ngôn ngữ “đánh dấu” HTML Dới đây là phần code:

Hình 15 Tạo văn bản HTML trong NotePad

Theo định dạng của ngôn ngữ HTML thì tài liệu đã đợc cấu trúc hoá mặc dù cha đợc chặt chẽ HTML sử dụng các thẻ để “đánh dấu”, ví dụ nh nội dung của một trang HTML nằm trong cặp thẻ và Sau đó là đến các thành phần nh Head, Title, Body Tất cả các đoạn code đều có chỗ xác định và mang ý nghĩa trong trang HTML ví dụ nh thẻ “đánh dấu” cho biết phần nội dung nằm giữa hai thẻ này phải đợc in đậm, thẻ xác định một chỗ xuống dòng

Hiện nay có hai loại ngôn ngữ đánh dấu đang đợc sử dụng đó là ngôn ngữ đánh dấu chuyên dụng và ngôn ngữ đánh dấu chung Ngôn ngữ đánh dấu chuyên dụng đợc sử dụng để tạo ra code chuyên dụng cho một trình ứng dụng nào đó hoặc thiết bị nào đó Các ngôn ngữ này đợc xây dựng phục vụ cho các mục đích chuyên biệt Ví dụ về ngôn ngữ đánh dấu chuyên dụng nh ngôn ngữ HTML để định dạng tài liệu cho mục đích Web hay ngôn ngữ RTF để định dạng văn bản Các ngôn ngữ này có đặc điểm là: số lợng các thẻ hạn chế, các tài liệu không có tính khả chuyển do đợc thiết kế cho một trình ứng dụng cụ thể.

Vào những năm 70 giáo s C.F.Goldfarb (hãng IBM) và các đồng nghiệp đa ra một phơng pháp diễn đạt văn bản không xác định riêng cho một trình ứng dụng hay một thiết bị nào Phơng pháp đó có hai điểm cơ bản, đó là: các ‘đánh dấu’ biểu thị cấu trúc của tài liệu chứ không diễn đạt cho việc định dạng kiểu văn bản và các qui tắc về ‘đánh dấu’ phải đợc thiết lập nghiêm ngặt sao cho code dễ hiểu đối với các ch- ơng trình và con ngời Kết quả của ý tởng trên làm tiền đề cho sự ra đời ngôn ngữDCF GML(Document Composition Facility Generalized Markup Language) do IBM phát triển Sau đó vào năm 1986 tổ chức ISO(International Srandard Organization) phê chuẩn ngôn ngữ SGML(Standard Generalized Markup Language)

Tổng quan về ngôn ngữ XML

II.1 Ngôn ngữ XML là gì?

Ngôn ngữ XML là ngôn ngữ thế hệ sau của SGML hay nói cách khác XML là tập con của SGML Không giống nh ngôn ngữ HTML ( HTML đợc coi là một ứng dụng của SGML bởi vì HTML đợc tạo ra dựa trên chuẩn SGML và nó kế thừa nhiều chi tiết từ SGML), XML là tập con của SGML và XML cũng đợc coi là một ‘siêu ngôn ngữ’ (ngôn ngữ có thể tạo ra các ngôn ngữ khác) XML đợc tối u hoá cho việc sử dụng trên World Wide Web và nó cung cấp cho ngời sử dụng thêm một số tiện ích khác mà SGML không hỗ trợ.

Nếu nh HTML thiên về biểu diễn thông tin thì XML thiên về việc mô tả thông tin XML là một chuẩn đợc sử dụng để cấu trúc và mô tả dữ liệu mà các ứng dụng khác nhau có thể sử dụng đợc Tính năng u việt của XML là ở chỗ nó tách biệt giữa giao diện ngời dùng và dữ liệu.

Nh vậy XML có thể đợc sử dụng nh là định dạng để trao đổi dữ liệu Rất nhiều các hệ thống, đợc gọi là các hệ di sản (legacy systems), có thể chứa dữ liệu theo các định dạng riêng biệt và các nhà phát triển đang cố gắng kết nối các hệ thống này sử dụng Internet Vấn đề là làm sao trao đổi dữ liệu giữa các hệ thống không tơng thích với nhau XML sẽ là giải pháp của vấn đề Các dữ liệu có thể đợc chuyển sang định dạng văn bản XML mà các ứng dụng hay các hệ thống khác nhau đều sử đụng đợc.

Bên cạnh đó, ta có thể sử dụng XML cho các dữ liệu Web Lúc đó trang HTML chỉ có nhiệm vụ định dạng về mặt trình bày còn dữ liệu đợc chứa trong file XML Do đó ta có thể cập nhật nội dung hay thậm chí là chuyển đổi nội dung của dữ liệu sang định dạng khác mà không phải thay đổi code HTML.

Ngoài ra XML còn đợc sử dụng để tạo ra các kho dữ liệu công cộng Một ví dụ điển hình là, nếu ngời sử dụng đang viết một bài báo cho một tạp chí Toà soạn báo muốn đồng thời đa bài báo lên Web site và tạp chí Nếu nh bài báo đợc định dạng theo RTF thì nó có thể phải đợc định dạng lại để có thể tải lên Web, sau đó nó phải định dạng một lần nữa để đa vào tạp chí xuất bản Tuy nhiên nếu bài báo đó đợc viết theo chuẩn XML thì nó có thể đợc kết xuất ra các môi trờng khác nhau một cách đồng thời bởi vì dữ liệu của bài báo và cách hiển thị tơng ứng là tách biệt nhau Hơn thế nữa các chơng trình ứng dụng để hiển thị dữ liệu chỉ cần đợc tạo ra một lần và ta có thể có thể sử dụng nó để hiển thị một số lợng bài báo tuỳ ý.

Nh vậy , XML là phơng thức hữu hiệu để lu trữ dữ liệu không những chỉ cho mục đích sử dụng trên Web mà còn đợc sử dụng trong các ứng dụng khác nhau.

II.2 Các u điểm của XML

Ngôn ngữ XML nhỏ hơn và đơn giản hơn so với SGML Nh đã nói ở trên XML đợc tạo ra với mục đích chủ yếu cho việc ứng dụng trên Web nên nó đã đợc cắt bỏ nhiều thành phần không cần thiết Các đặc tả về SGML dài 155 trang trong khi đặc tả về XML chỉ dài 35 trang.

XML bao gồm thêm tính năng siêu liên kết đợc mô tả nh một ngôn ngữ tách biệt có tên là XLL(Extensible Linking Language) Trong khi đó SGML không bao gồm tính năng này mà nó chỉ coi đó là một thành phần đợc phép thêm vào.

XML bao gồm một đặc tả về ngôn ngữ định kiểu có tên là :XSL(Extensible Stylesheet Language) Đây là ngôn ngữ cung cấp cho ngời sử dụng các hỗ trợ về ứng dụng bản định kiểu(style-sheets) mà SGML không có Các bản định kiểu cho phép ngời sử dụng tạo ra các bản mẫu (template) có các kiểu cách khác nhau (ví dụ nh in đậm, in nghiêng ) hoặc kết hợp các kiểu cách khác nhau vào trong các thành phần trong một tài liệu.

Hiện nay W3C đa ra khuyến cáo về đặc tả XML1.0 XML đang tiến dần đến việc đáp ứng cho nhu cầu sử dụng rộng rãi Tuy nhiên đây mới chỉ là khuyến cáo của một tổ chức chứ cha phải là một chuẩn.

II.3 Các ứng dụng XML

II.3.1 Mathematical Markup Language (MathML)

MathML 1.0 mới đợc tổ chức W3C khuyến cáo gần đây MathML là một ứng dụng XML đợc thiết kế để tạo thuận lợi cho việc sử dụng các công thức toán học cũng nh các nội dung mang tính khoa học trên Web

II.3.2 Resource Description Framework(RDF)

RDF là trạm mô hình dữ liệu phục vụ nh là một kho để xử lí các siêu dữ liệu RDF sử dụng XML để làm cú pháp mã hoá mặc dù tồn tại nhiều cách khác để biểu thị mô hình RDF Tuy nhiên các đặc tả cú pháp và mô hình RDF mới chỉ trong giai đoạn thử nghiệm.

II.3.3 XML Linking Language(XLink)

XLink là ứng dụng XML tạo ra bộ máy để kết nối các tài liêụ XML XLink bao gồm khả năng kết nối nhiều nguồn khác nhau Mặt khác, XLinhk cho phép liên kết các định dạng dữ liệu khác nhau nh là hình ảnh Ngoài ra XLink còn cung cấp tiện ích liên kết ‘thông minh’ có thể liên kết động và lọc liên kết dựa trên nội dung và ngữ cảnh.

II.3.4 Synchronized Multimedia Intergration Language(SMIL)

SMIL là ứng dụng XML cho phép sử dụng các truyền thông đa phơng tiện trên Web Điểm mạnh của SMIL là nó cho phép ngời sử dụng tạo ra các truyền thông đa phơng tiện phức tạp, đồng bộ mà không phải chuyển nội dung sang định dạng khác nh là video hay sử dụng các ngôn ngữ script phức tạp Tổ chức W3C vừa đa ra khuyến cáo về SMIL 1.0.

II.3.5 Extensible Stylesheet Language(XSL)

XSL là ngôn ngữ định dạng văn bản đợc thiết kế một cách linh hoạt và có tính mở XSL lấy các CSS ( Cascading Style Sheets – bản kiểu dáng liên hoàn) để thực hiện các tác vụ định dạng phức tạp nh thể là code đợc nhúng trong các bản kiểu dáng. XSL mới trong giai đoạn thử nghiệm

Cấu trúc và cú pháp XML

Nh đã trình bày ở trên,u điểm của XML là nó có tạo ra các tài liệu có cấu trúc. Mỗi tài liệu XML có hai cấu trúc là: cấu trúc vật lí và cấu trúc logic Ví dụ ở hình vẽ díi ®©y:

Hình 16 Cấu trúc của XML

Cấu trúc logic của XML đợc xem nh là một bản mẫu thể hiện các thành tố trong một tài liệu theo một thứ tự nhất định Cấu trúc logic mô tả cách xây dựng một tài liệu chứ không phải mô tả tài liệu đó chứa cái gì.

Thành phần đầu tiên của tài liệu là tùy chọn ‘prolog’ ’Prolog’ bao gồm hai phần chính là khai báo XML và khai báo kiểu tài liệu.

 Khai báo XML: khai báo XML xác định phiên bản của đặc tả XML mà tài liệu tuân theo Ngoài ra khai báo XML còn có thể chứa khai báo mã hoá xác định cách mã hoá các kí tự trong tài liệu và khai báo tài liệu tách biệt (stand-alone declaration) xác định các khai báo ‘đánh dấu’ có nằm ngoài tài liệu hay không.Ví dụ :

 Khai báo kiểu tài liệu: khai báo kiểu tài liệu chứa các code ‘đánh dấu’ xác định các quy tắc ngữ pháp hay còn gọi là DTD ( Document Type Definition) cho một lớp đặc biệt nào đó trong tài liệu Khai báo này còn có trỏ tới các file khác chứa các DTD Khai báo này phải đi sau khai báo kiểu XML và đứng trớc các thành phần của tài liệu.Ví dụ nh khai báo sau:

Khai báo này báo cho trình xử lí XML biết đợc tài liệu này thuộc lớp

Detail và nó phải tuân theo các quy định đợc định nghĩa trong file

Tiếp theo là các thành phần của tài liệu, phần chính của một tài liệu XML, nơi chứa các nội dung chính Các thành phần tài liệu này còn có thể bao gồm các thành phần tài liệu con và cả các thực thể ngoài XML có cấu trúc cây, nó bao gồm một thành phần gốc và các thành phần con sau đó là các thành phần kế tiếp (có thể rỗng). Mỗi thành phần có tên và có thể có các thuộc tính Ví dụ:

Hình 17 Khai báo thành phần trong XML

III.1.2 CÊu tróc vËt lÝ

Cấu trúc vật lí của XML chứa dữ liệu thực đợc sử dụng trong tài liệu XML. Các dữ liệu này có thể là văn bản chứa trong bộ nhớ máy tính, file hình ảnh trên World Wide Web Nếu nh cấu trúc logic là bản thiết kế ngôi nhà thì cấu trúc vật lí chính là không gian thật chứa ngôi nhà đó Ngôi nhà có chứa các đồ đạc hay gọi là các thực thể Mỗi một thực thể có tên riêng và có nội dung riêng, nội dung này có thể nằm trong tài liệu hoặc là một file ngoài tài liệu Các thực thể đợc khai báo trong phần ‘prolog’ và đợc tham chiếu trong các thành phần của tài liệu Thực thể chia làm hai loại là thực thể phân tách và thực thể không phân tách.

 Thực thể phân tách hay còn đợc gọi là thực thể văn bản ,chứa các dữ liệu văn bản ,trờ thành một phần của tài liệu XML Khi một trình xử lí XML phân tách các thực thể này ,nội dung của chúng xuất hiện nh một phần của tài liệu tại nơi tham chiếu thực thể Ví dụ nh ta có khai báo nh sau : .

Mỗi khi thực thể đợc tham chiếu trong tài liệu thì nội dung của nó sẽ đợc đặt vào nơi tham chiếu đó Nếu muốn thay đổi nội dung của thực thể thì ta chỉ cần thay đổi ở khai báo, sau đó thay đổi này đợc ánh xạ tới những nơi mà tham chiếu tới thực thể.

 Thực thể không phân tách đợc coi nh là một thùng chứa mà nội dung của nó có thể có hay không có văn bản Thực thể không phân tách đợc đôi khi còn có tên là thực thể nhị phân bởi vì nội dung của nó thờng là file nhị phân(ví dụ nh file ảnh) và trình xử lí XML không trực tiếp thông dịch đợc Khai báo một thực thể không phân tách đợc cần một chú thích để xác định kiểu định dạng hay kiểu hay nguồn của thực thể Ví dụ nh khai báo sau :

Ngoài ra các chú thích cũng cần đợc khai báo Các khai báo chú thích giúp cho trình xử lí XML thao tác trên các file nhị phân Ví dụ nh ta có thể khai báo chú thích cho ví dụ trên :.

Thực thể tiền định nghĩa:Trong XML một số kí tự nào đó đợc sử dụng để ‘đánh dấu’ tài liệu.Trong ví dụ sau thành phần Person đợc xem nh là một ‘đánh dấu’ và không đợc coi là dữ liệu kí tự : Bill Theo W3C tất cả các trình xử lí XML đều nhận biết các tham chiếu thực thể tiền định nghĩa mặc dù các thực thể này không đợc khai báo Vì vậy chỉ có các thực thể đợc khai báo trong DTD của tài liệu mới đợc xem là hợp lệ.

Nội thực thể trong và ngoại thực thể: Thực thể trong là các thực thể mà nội dung của nó xuất hiện trong phần khai báo (ví dụ trên E là nội thực thể ) tức là không tồn tại một đơn vị vật lí tách biệt nào chứa nó Thực thể ngoài là nói đến một đơn vị chứa trong khai báo của nó bằng cách sử dụng các định danh hệ thống hoặc định danh công cộng Ví dụ nh khai báo sau:

Trong ví dụ này trình xử lí XML phải đọc file I1.gif để lấy nội dung Ngoài ra các định danh công cộng đợc sử dụng nếu nh trình ứng dụng đợc kết nối với một th viện tài liệu công cộng Ví dụ khai báo sau:

PUBLIC “-//Image//TEXT Standard images//EN”

“http://www.myname.com/Images/I1.gif

Trong phần này chúng ta tìm hiểu cú pháp cơ bản của tài liệu XML Vì HTML và XML đều là các ứng dụng từ SGML nên đối với những ai đã từng làm việc với HTML sẽ thấy một số điểm tơng đồng về cú pháp giữa chúng tuy là chúng không hoàn toàn có cùng ý nghĩa.

III.2.1 Các thẻ gán và phần tử

Trong HTML, các thành phần thờng sử dụng các thẻ đóng và thẻ mở ví dụ nh

và “

” Do HTML đợc giản lợc bớt nên ở một số chỗ mặc dù không có thẻ đóng nhng trình xử lí vẫn hiểu đợc Tuy nhiên XML không cho phép điều đó, mỗi một thẻ mở trong XML phải luôn tồn tại một thẻ đóng tơng ứng Điều này làm cho cú pháp của XML chặt chẽ và sáng sủa hơn so với HTML.

Ta xem vÝ dô sau:

Hình 18 Minh họa cấu trúc cây của ví dụ

XML trong C#

Trong phần này chúng ta tìm hiểu cách thức C# hỗ trợ chuẩn XML Trong C# có cung cấp một không gian tên System.Xml bao gồm nhiều tiện ích để ta có thể làm việc với các tài liệu XML Do giới hạn về thời gian, tài liệu nên trong phần này chúng em chỉ đi sâu vào một số vấn đề chính.

IV.1 Tạo một tài liệu XML

Giả sử ta muốn tạo một tài liệu XML có cấu trúc nh sau:

Chơng trình sau sẽ tạo ra file ‘c:\car.xml’ using System; using System.IO; using System.Xml; using System.Text; class CarDomWriter {

XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "UTF-8", null); doc.AppendChild(decl);

XmlNode root = CreateCarNode(doc); doc.AppendChild(root);

XmlTextWriter writer = new XmlTextWriter(outStr, new UTF8Encoding()); writer.Formatting = Formatting.Indented; doc.WriteTo(writer); writer.Flush(); writer.Close();

XmlElement car = doc.CreateElement("Car"); car.SetAttribute("VIN","123");

XmlNode model = CreateModelNode(doc); car.AppendChild(model);

XmlNode miles = CreateMilesNode(doc); car.AppendChild(miles); return car;

XmlElement model = doc.CreateElement("Model");

XmlElement year = doc.CreateElement("Year"); year.InnerText = "1998"; model.AppendChild(year);

4 8 mfr.InnerText = "Honda"; model.AppendChild(mfr);

XmlElement make = doc.CreateElement("Make"); make.InnerText = "Civic"; model.AppendChild(make); return model;

XmlElement miles = doc.CreateElement("Mileage"); miles.SetAttribute("Units", "Miles"); miles.InnerText = "80000"; return miles;

"c:\\car.xml",FileMode.Create); try { new CarDomWriter(outStr);

Thao tác đầu tiên là tạo một đối tợng XmlDocument, sau đó ta lần lợt tạo ra các node và gắn chúng vào XmlDocument Ta gắn một node vừa tạo bằng phơng thức XmlDocument.AppendChild() Sau khi tạo khai báo ( coi nh một node và gắn vào XmlDocument ), ta tạo node gốc là Car Cứ tiếp tục quá trình tạo ra các node tiếp theo, nếu node nào đó có thuộc tính ta dùng phơng thức XmlElement.SetAttribute(). Sau khi hình thành đợc cấu trúc XML, ta tạo một đối tợng XmlTextWriter để có thể ghi lên luồng file ra FileStream.XmlDocument.WriteTo() nhận XmlTextWriter làm tham số, và ghi lên đó cấu trúc của tài liệu XML Thao tác cuối cùng là đẩy dữ liệu ở bộ nhớ vào luồng file ra bằng việc gọi phơng thức XmlTextWriter.Close().

Xem kết quả bằng trình duyệt IE 6.0:

Hình 19 Kết quả chơng trình tạo tài liệu trên IE 6.0

IV.2 Duyệt tài liệu XML

Giả sử sau khi đã tạo ra tài liệu XML nh trên, ta muốn duyệt tài liệu đó Trong C# tồn tại hai kiểu duyệt đó là duyệt theo luồng và duyệt theo cây Duyệt theo luồng là duyệt mà ở đó ta mở một luồng dữ liệu vào và duyệt luồng dữ liệu này một cách liên tục không qua bộ đệm và không cần tạo ra đối tợng cho mỗi node Cách duyệt này tăng hiệu năng của quá trình duyệt và ứng dụng cho các tài liệu XML cỡ lớn. Cách duyệt thứ hai là duyệt theo cây, ở đây toàn bộ cấu trúc của file đợc tải vào bộ nhớ sau đó ta tiến hành duyệt theo từng node Quá trình duyệt sử dụng thuật toán đệ qui Trong ví dụ dới đây ta sử dụng cách duyệt theo cây:

Chơng trình sau sẽ duyệt file ‘c:\car.xml’ using System; using System.IO; using System.Xml; class CarReader {

XmlDocument doc = new XmlDocument(); doc.Load(fileName);

Console.WriteLine("Current node is of type {0}", node.NodeType); if (node.NodeType == XmlNodeType.Element) {

Console.WriteLine("", node.Name); foreach(XmlAttribute att in node.Attributes){

} if (node.NodeType == XmlNodeType.Text) {

Console.WriteLine("Text = " + node.Value);

} foreach(XmlNode child in node.ChildNodes){

} public static void Main(){ new CarReader("c:\\car.xml");

Kết quả thu đợc nh sau:

Không gian tên System.Xml.Serialization cung cấp cho chúng ta khả năng chuyển đổi từ t liệu XML sang các dạng cấu trúc dữ liệu khác trên cùng một miền (Deserializing) và chuyển từ tập các đối tợng có thể tạo ra một t liệu XML chuẩn (Serializing).

Quá trình serializing chỉ chuyển hoá các thuộc tính public của một đối tợng (hoặc là trờng public của một đối tợng –tuy nhiên ít dùng) Bên cạnh đó quá trình chuyển hoá yêu cầu lớp của đối tợng là lớp public và hàm khởi tạo không có tham số truyền vào Điều này để tránh xung đột giữa trạng thái trong của một đối tợng.

Ta xét ví dụ trên, ta tạo một đối tợng từ lớp Car, với các thuộc tính public và ứng với mỗi thuộc tính của đối tợng nếu ta muốn sau quá trình chuyển hoá nó đợc chuyển thành thuộc tính của thành phần của XML thì ta thêm [XmlAttribute] vào tr- ớc đoạn code đó Sau khi tạo đối tợng rồi, ta tiến hành chuyển hoá bằng cách tạo ra một XmlSerializer và dùng phơng thức XmlSerializer.Serialize() với tham số là đối t- ợng c và một XmlTextWriter để ghi ra dòng file Sau đây là code: using System; using System.Xml.Serialization; using System.IO; using System.Text; using System.Xml; public class Car { public Car(){ } string vin;

[XmlAttribute] public string VIN{ get { return vin;} set { vin = value;}

Model model; public Model Model{ get { return model;} set { model = value;}

Mileage miles; public Mileage Mileage{ get { return miles;} set { miles = value;}

Car c = new Car(); c.VIN = "123"; c.Model = new Model(1998, "Honda", "Civic"); c.Mileage = new Mileage("Miles", 80000);

XmlSerializer xs = new XmlSerializer(typeof(Car));

FileStream outStr=new FileStream(“c:\\ser_car.xml”,

XmlTextWriter writer=new XmlTextWriter(outStr, new UTF8Encoding()); writer.Formatting=Formatting.Indented; xs.Serialize(writer, c); writer.Flush(); writer.Close();

} public class Model { public Model(){

} public Model(int yr, string mfr, string make){ this.yr = yr; this.mfr = mfr; this.make = make;

} int yr; public int Year{ get { return yr;} set { yr = value;}

[XmlElement("Maker")] public string Maker{ get { return mfr;} set { mfr = value;}

} string make; public string Make{ get { return make;} set { make = value;}

} public class Mileage { string units;

[XmlAttribute("Units")] public string Units{ get { return units;} set { units = value;}

[XmlText] public int Quantity{ get { return val;} set { val = value;}

} public Mileage(){ } public Mileage(string units, int val){ this.units = units; this.val = val;

Hình 20 Kết quả ví dụ Serializing trên IE 6.0

IV.4 Quá trình Deserializing Đây là quá trình ngợc lại so với quá trình Serializing Quá trình chuyển hoá sẽ chuyển một t liệu XML thành một đối tợng cùng kiểu.

Ví dụ sau ,ta chuyển tài liệu XML ‘c:\car.xml’ thành đối tợng car tơng ứng với điều kiện ta phải khai báo lớp Car trong chơng trình (nh ví dụ phần trớc).Kết quả đợc kÕt xuÊt ra console: using System; using System.IO; using System.Xml.Serialization; public class CarFromFile { public static void Main(){

XmlSerializer xs = new XmlSerializer(typeof(Car));

FileStream str = new FileStream("c:\\car.xml", FileMode.Open);

Car c = (Car) xs.Deserialize(str); str.Close();

Console.WriteLine("{0} {1} {2}, {3} {4}", c.Model.Year, c.Model.Maker, c.Model.Make, c.Mileage.Quantity, c.Mileage.Units);

Lập trình mạng trong C#

Giới thiệu về lập trình mạng

Lập trình mạng trong NET thật dể dàng Đặc điểm của các chương trình ứng dụng mạng với công nghệ NET là có rất nhiều mã code được cung cấp sẵn Khuynh hướng này được mang lại một cách đầy đủ với WebmethodAttribute. WebmethodAttribute dường như một cách thường xuyên khi thể hiện các phương thức trong lập trình Web Chúng ta sẽ xem xÐt một cách rõ ràng cách để chuyển dữ liệu lưu thông trên mạng.

Trước tiên chúng ta sẽ học cách để nhận dạng machine Tất nhiên, để giao tiếp với một máy từ máy khác phải chắc chắn rằng bạn đã kết nối với máy mà bạn muốn giao tiếp, chính vì thế phải có một số cách để nhận dạng các máy riêng biệt trên một mạng Trước đây, một chuẩn thống nhất được đưa ra với mạng cục bộ Tuy nhiên với IP(Internet Protocol) trở thành một chuẩn thường được sử dụng nhất trong việc kết nối giữa các máy tính Đó chính là sự thành công của địa chỉ IP, chỉ với 32 bit số để mô tả Theo đó DNS (Domain Name Service) được sữ dụng để tìm kiếm các địa chỉ

.NET cung cấp lớp IPAddress để đóng gói các địa chỉ Chóng ta có thể tạo một địa chỉ IPAddress với 32 bit số đặc biệt, nhưng dùng phương thức IPAddress.Parse() để tạo nên một địa chỉ IP hoặc sữ dụng các phương thức như Resolve() hay GetHostByName() của lớp Dns Chương trình sau sử dụng phương thức Dns.GetHostByName() để tạo ra địa chỉ IP của bạn Để sử dụng hiệu quả chóng ta nên biết tên máy của m×nh.

//Resolves current IP addresses using System; using System.Net; class WhoAmI { public static void Main(string[] args){ string machineName = args.Length == 0 ?

Dns.GetHostByName(machineName); foreach(IPAddress ip in addresses.AddressList){

Nếu chạy nó không có tham số trong dòng lệnh , nó sẽ trả về địa chỉ

“localhost” đó là 127.0.0.1 Bạn có thể dùng nó để tìm địa chỉ IP của trang www.microsoft.com.

Thêm vào phần địa chỉ, IP còn sử dụng thêm một định vị đặc biệt thứ hai gọi là Port Port có thể xem nh là một cổng lô - gic qui định nơi ra, vào dữ liệu của các ch- ơng trình Các chơng trình sẽ luôn ‘lắng nghe’ tại các Port xem có dữ liệu vào hay không và khi nó cần chuyển dữ liệu cho trơng trình khác nó cũng phải chuyển đến đúng Port qui định của chơng trình đó

Trong giao thức mạng máy tính TCP/IP, một Socket bao gồm một địa chỉ IP và một địa chỉ cổng Dữ liệu chuyển qua Internet được chia thành cỏc gúi, mỗi gúi chứa một header bao gồm thụng tin địa chỉ và lượng dữ liệu Cụng nghệ NET thực hiện chóng thông qua Sockets và các lớp liên quan trong không gian tên System.Net.Sockets.

Trong NET Framework chúng ta sử dụng một socket để kết nối hai mỏy, tiếp đến chóng ta sẽ có một NetworkStream cho phép thao tác socket giống như thao tác với các đối tượng vào ra bình thường khác Chóng ta có được NetworkStream này từ lớp Socket thụng qua sử dụng một TcpListener giống như một server dựng để lắng nghe các yêu cầu kết nối và một TcpClient dùng giống như một client để khởi tạo kết nối Trước tiên client sẽ tạo một socket kết nối và TcpListener sẽ trả lời bằng phương thức AcceptTcpClient() Tiếp theo chóng ta có một kết nối giữa TcpClient và một TcpClient Lúc này chóng ta sử dụng TcpClient.GetStream() để tạo ra một đối tượng NetworkStream từ mỗi TcpClient

Tiếp nhận sự kết nối: Để tạo ra một server của chính chóng ta, chóng ta sẽ phải sữ dụng lớp TcpLístener Chương trình sau sẽ là một ví dụ để tạo ra một server rất đơn giản Nhiệm vụ của server là chờ kết nối, dùng TcpClient để sản xuất ra mộtNetworkStream Sau đó, mọi thứ được đọc vào sẽ được hiện ra trên màn hình server,đến khi gặp dòng END thì ngừng kết nối.

Client tạo một kết nối với server sau đú tạo một NetworkStream Cỏc dòng text sẽ được gửi theo các Stream và các dòng nhận được sẽ in ra trên màn hình Console : using System; using System.Net; using System.Net.Sockets; using System.IO; public class JabberServer {

// Choose a port outside of the range 1-1024: public static readonly int PORT = 1711; public static void Main(){

TcpListener server = new TcpListener(PORT);

TcpClient cnxn = null; try { server.Start();

// Blocks until a connection occurs: cnxn = server.AcceptTcpClient();

StreamReader reader = new StreamReader(cnxn.GetStream());

StreamWriter writer = new StreamWriter(cnxn.GetStream()); writer.AutoFlush = true;

Console.WriteLine("Beginning receive loop"); while (true) {

String str = reader.ReadLine(); if (str == "END") break;

Console.WriteLine("Echoing: " + str); writer.WriteLine(str);

Console.WriteLine("closing "); cnxn.Close();

Chóng ta có thể thấy là TcpListener chỉ cần chỉ số của port, không phải là một địa chỉ IP (tính khi chạy trên chính máy này) Chóng ta gọi phương thức TcpListener.Start() và TcpListener.Stop() để điều khiển khi chóng ta muốn lắng nghe từ cổng Sau khi đã gọi TcpListener.Start(), gọi TcpListener.AcceptTcpClient(), khối này sẽ lặp cho đến khi nhận được kết nối đến nó Nghĩa là nó sẽ chờ kết nối nhưng các quá trình khác vẩn tiếp tục chạy Khi kết nối được thiết lập, TcpListener.AcceptTcpClient() trả về đối tượng TcpClient đại diện cho kết nối đó.

Sự phản hồi được quét dọn một cách thủ công ở đây Bộ try-finally được sử dụng để đảm bảo rằng cả đóng TcpClient cnxn và dừng TcpListener Nếu ServerSocket khởi tạo bị lỗi, chương trình sẽ thoát ra ngoài Trong trường hợp này, main( ) tung ra

IOException nên khối lệnh try không được dùng Nếu ServerSocket khởi tạo thành công thì tất cả các phương thức khác được gọi phải được che trong khối try-finally để bảo vệ nó Giá trị logic dùng trong Socket được trả về bởi Accept() Nếu Accept bị lỗi thì chúng ta phải thừa nhận rằng Socket không tồn tại và giữ bất cứ tài nguyên nào, cho nên nó không cần được dọn sạch Nếu thành công, tuy nhiên, tùy thuộc nằm trong khối try-finally thì nếu nó bị lỗi Socket sẽ vẫn được làm sạch Cẩn thận với yêu cầu ở đây Socket dùng các tài nguyên quan trọng không chiếm trong bộ nhớ.

Phần tiếp theo trông giống như việc mở một files và thực hiện các thao tác đọc ghi trên file StreamReader và StreamWriter được tạo từ đối tượng NetworkStream được trả về bởi TcpClient.GetStream() Đối tượng StreamWriter có thuộc tính Autoflush được thiết lập bằng true sau mỗi lần gọi StreamWriter.Write( ) hay

StreamWriter.WriteLine( ) bộ đệm sẽ được gửi qua mạng Làm sạch Flushing thật quan trọng trong ví dụ này vì máy client và server mỗi lần đợi bộ phận kia trước khi xử lý Nếu flushing không được thực hiện, thông tin có thể không được gửi lên mạng cho đến khi bộ đệm bị tràn Kết quả trong chương trình chỉ ngồi chờ sau khi kết nối được khởi tạo.

Khi viết một ứng dụng mạng chúng ta cần phải cẩn thận khi sử dụng automatic flushing Mỗi lần chóng ta flush làm sạch bộ đệm buffer thì một gói phải được khởi tạo và gửi đi Trong trường hợp này, chính xác những gì chúng ta muốn, từ đó nếu gói tin chứa dòng dữ liệu không được gửi thì bắt tay trở lại và đến lần thứ 4 giữa server và client sẽ dừng Thêm vào cách khác, kết thúc dòng là kết thúc lời nhắn. Nhưng trong nhiều trường hợp, lời nhắn không giới hạn bởi các dòng thì không dùng auto flushing và thay vào đó cho phép giải quyết phân chia buffer khi tạo và gửi một gói tin Với cách này, các gói tin lớn có thể được gửi và xử lý nhanh hơn Vòng while lặp vô tận để đọc các dòng từ StreamReader reader và ghi thông tin ra màn hình Console và đến StreamWriter writer Chú ý reader và writer cũng giống như bất kỳ dòng tin nào, chúng chỉ được dùng để kết nối dòng tin trên mạng Khi Client gửi dòng tin “END” thì chương trình sẽ ngưng vòng lặp, đóng TcpClient, và dừng TcpListener Ví dụ sau đây sẽ tạo Client để kết nối với Server: using System; using System.Net; using System.Net.Sockets; using System.IO; public class JabberClient { private static readonly int PORT = 1711; public static void Main(string[] args){

IPAddress addr = IPAddress.Loopback; if (args.Length == 1) { addr = Dns.Resolve(args[0]).AddressList[0];

Console.WriteLine("addr = " + addr.ToString());

// Guard everything in a try-finally to make

// sure that the socket is closed: try {

Console.WriteLine("Client = " + client); client.Connect(addr, PORT);

StreamReader reader = new StreamReader(client.GetStream());

StreamWriter writer = new StreamWriter(client.GetStream()); writer.AutoFlush = true; for (int i = 0; i < 10; i ++) { writer.WriteLine("howdy " + i); string str = reader.ReadLine();

Console.WriteLine("closing "); client.Close();

Dns.Ressolve được dùng để lấy địa chỉ IPAddress Nếu chương trình chạy với không tham số thì IPAddress được thiết lập là địa chỉ IP 127.0.0.1 TcpClient dùng phương thức TcpClient.Connect() để tạo kết nối với server, xử lý tạo kết nối NetworkStream vào trong StreamReader và StreamWriter được thực hiện cùng với server Ở đây thuộc tính auto flushing được thiết lập bằng true Mỗi dòng được gửi từ server được viết trở lại vào console Client dùng dòng lệnh “END” để kết thúc kết nối.

Giao tiÕp víi Web

II.1 Gửi và nhận các yêu cầu HTTP

Tiếp theo chúng ta sẽ thảo luận về vấn đề rất hay, đó là việc tạo cũng như nhận cỏc yờu cầu HTTP requests, chỳng ta sẽ núi về lập trỡnh World Wide Web Như mọi ngời đó biết World Wide Web là cơ sở của Hypertext Transport Protocol (HTTP).Tất nhiên, hầu hết các trình ứng dụng đều có kiểu HTTP request từ trình duyệt WebBrowser, nhưng thật hữu ích nếu, đặc biệt là với mục đích gỡ lỗi thì chúng ta cần biết lập trình với HTTP Requests .NET Framework SDK cung cấp các lớp để chúng ta thao tác một cách dể dàng, đó là lớp WebRequest và lớp HttpWebResquest trong không gian tên System.Net Yêu cầu HTTP đơn giản nhất là gửi là gửi yêu cầu HTTPGET đến Uniform Resource Identifier riêng biệt Và HTTP Server (Web Server) sẽ gửi thông tin phản hồi với một status code, một header, và một message body Ví dụ sau thực hiện yêu cầu trên: using System; using System.Net; using System.IO; class HttpGet { public static void Main(string[] args){

Console.WriteLine("Created, but not connected");

Console.WriteLine("Status: " + res.StatusCode); foreach(string key in res.Headers.Keys){

Console.WriteLine("Header[{0}]:{1}", key, res.Headers[key]);

StreamReader rdr = new StreamReader( res.GetResponseStream());

Cách khởi tạo HttpWebRequest cũng giống như trong các ví dụ trước Ta tạo ra một biến kiểu HttpWebRequest và cho nó trỏ đến đối tượng kiểu WebRequest. Một kiểu khác của WebRequest trong NET Framework SDK là FileWebRequest, được khởi tạo bằng cách đưa vào tham số đối với WebRequest.Start() là “file://,” nhưng nếu bạn viết kiểu “ftp://” bạn có thể gọi phương thức tĩnh WebRequest.RegisterPrefix() và WebRequest.Create() sẽ trả về sau đó một WebRequest mới Yêu cầu Request sẽ không mang tính thực tế chuyển tải trên mạng cho đến khi gọi WebRequest.GetResponse() Bởi vỡ chỳng ta biết rằng chỳng ta đang phân chia yêu cầu bắt đầu với “http://” Sau khi nhận về HttpWebRespone.StatusCode, sau đó chúng ta viết Http header vào Console Tiêu đề header chính là thuộc tính HttpWebResponse.Header xuất phát từ đối tượng WebHeaderCollection là kiểu con của NameValueCollection.

.NET Framework SDK được thiết kế có hổ trợ Microsoft’s InternetInformation Server (IIS) và hầu hết các hình thức truy cập trực tiếp đều có hổ trợ giao diện IHttpHandler trong không gian tên System.Web IHttpHandler định nghĩa hai thứ: một thuộc tính bool được gọi là IsReusable chỉ rõ đối tượng với khả năng bảo vệ Http Request Khi đang viết một chương trình Web thành phần đòi hỏi trạng thái giảm đến mức tối đa server của bạn Chính vì vậy nên thích hợp hơn khi bạn đặt thuộc tính này là true Thành phần thức hai của IHttpHandler là phương thứcIHttpHandler.ProcessRequest(), đây là phương thức tạo ra đối tượng HttpContext.Thuộc tính quan trọng nhất trong HttpContext là các đối tượng HttpRequest và

HttpResponse (chú ý rằng các lớp này khác với các lớp mà được dùng tại client HttpWebRequest và HttpWebResponse) HttpRequest chứa một số lượng lớn các thuộc tính, hầu hết được dùng với thuộc tính HttpRequest.Form, trả về NameValueCollection với các định dạng tên biến và giá trị là kiểu string.

II.2 Các yêu cầu Web không đồng bộ

Vấn đề không được thảo luận ở phần trước đó là phần giao diện của dòng tin NET Framework IO stream có hổ trợ vào ra không đồng bộ, được gọi để đọc hoặc viết một dũng tin khụng phải là gúi Sự khụng đồng bộ trong IO sử dụng thiết kế khụng đồng bộ mà Microsoft chủ trương phỏt triển rộng trong sử dụng: đú là cú một khai báo bắt đầu và kết thúc operation và kích hoạt kiểu đại diện không đồng bộ: public delegate void AsyncCallback(IAsyncResult ar);

IasyncResult ar có một số trường chứa:

 Một Object AsyncState là một đối tượng domain phản chiếu bất kỳ trạng thái nào cần thiết cho hàm gọi ngược trở lại.

 WaitHandler AsyncWaitHandler có thể dùng đồng bộ nhiều tiến trình phức tạp trong các điều hành không đồng bộ.

 CompletedSynchronously and IsCompleted là hai thuộc tính kiểu bool xác định khi sự đồng bộ hóa begin operation hoàn thành và khi end operation kết thúc.

Trong trường hợp WebRequest, sự đồng bộ hóa được gọi đến phương thức WebRequest.GetResponse() cùng phản hồi cùng lúc với phương thức bắt đầu begin và kết thúc end của WebRequest.BeginGetResponse( ),

WebRequest.EndGetResponse( ) Để thiết lập một Web request thùc sự đồng bộ chóng ta nên dùng những phương thức này cho quá trình đọc không đồng bộ của các dòng Stream phản hồi dùng Stream.BeginRead() và Stream.EndRead().

WebServices không là các trình ứng dụng đứng đầu trong việc thức hiện vào ra để gửi với chuẩn Internet Protocol Với “headless”, chúng ta hiểu rằngWebServices không có phần giao diện người dùng (tất nhiên giao diện người dùng cuối cùng thì cũng cần thiết, nhưng nó được thiết lập bởi một số thành phần khác chứ không phải WebServices Thay vì các đối tượng hay các mã HTML (các thành phần giao diện), WebServices dùng tài liệu XML đối với việc vào và ra dữ liệu Cách màXML input tạo ra và XML output xóa như thế nào không phải là nội dung cần quan tâm của WebServices Với “Standard Internet Protocols”, chúng ta có được nhiều khả năng thao tác Khi mà WebServices trở thành từ thông dụng thì các biến tự động hoàn thành bằng cách nhìn vào danh sách các đặc điểm của chúng và nói rằng “Nếu không hổ trợ giao thức này thì không thể hoàn thành được” hay là “Giao thức này thật là thiết kế mỡ rộng để giải quyết vấn đề của chúng ta” Theo hướng đó có nhiều chuẩn đối lập nhau đối với bản chất của các chức năng, bao gồm ý nghĩa các thủ tục của thủ tục được gọi và ý nghĩa mà WebServices mô tả Cấu trúc chính là các quyết định bình phẩm đối với WebServices nhưng NET vẫn kiên quyết theo phía của Simple Object Access Protocol (SOAP)

Sau đây là một ví dụ đơn giản của WebServices : chương trình “Hello,C#” được kết hợp với WebMethodAttribute Như là một thành phần của trình biên dịch, Visual Studio NET nhận ra thuộc tính này và tự động đưa lên IIS qua dịch vụ SOAP. IIS điều đầu cuối của URI thông qua file asmx với các công cụ của WebServices. File này phải có dòng khai báo WebServices riêng ở đầu, nhưng hơn hết là sau đó thì các thuộc tính được hoàn toàn Ví dụ này sẽ trả về thời gian time của server hiện tại:

using System; using System.Web.Services;

[WebService(Namespace="http://localhost/")] class WhatsTheTime{

[WebMethod] public DateTime Time(){ return DateTime.Now;

File được save dưới dạng Xxx.asmx, nó phải được thêm vào khai báo , phương thức được khai báo dạng public và kết hợp với WebMethodAttribute và server của bạn phải cài nền NET Framework IIS cung cấp một dịch vụ được mô tả trong Web Services Description Language (WSDL) Khi bạn khai báo :

Thì phương thức WebMethodAttribute trong kiểu Type sẽ được load từ Asssemble trong thư mục con /bin Khi bạn dùng Visual Studio NET để tạo một WebServices Project thì kiểu của WebServices phải được khai báo Khối trong khai báo trang ASP.NET Cũng giống như ADO.NET hay XML thì trang ASP.NET cũng là một công nghệ được tạo nên với C#, nhưng nó không phải là một tập con ASP.NET được biên dịch thành khối các mã lệnh HTML (giống WebServices đã khai báo ở trên) Chúng ta không nói nhiều về ASP.NET ở đây mà sẽ trình bày về nó trong tài liệu khác.

Một vài so sánh C# với các ngôn ngữ khác

Sự khác nhau giữa C# và C/C++

Mã của C# rất quen thuộc với những ngời đã lập trình C và C++, tuy nhiên vẫn có một vài khác biệt.

C# chạy trên môi trờng là nền NET, điều này có nghĩa là có nhiều thứ đợc thực hiện tự động, không cần sự điều khiển của ngời lập trình, cụ thể nh sau:

 Việc xoá bỏ các đối tợng đợc thực hiện tự động bởi GC khi không còn bộ nhớ để cấp phát GC cũng có thể gọi để thực hiện thu hồi bộ nhớ trong những trờng hợp cá biệt Trong khi đó, ngời lập trình C++ luôn phải đảm nhiệm việc quản lí bộ nhớ.

 Hoàn toàn không có kiểu con trỏ trong ngôn ngữ C# Thay vào đó là kiểu dữ liệu tham trị, có thể hoạt động nh con trỏ nhng dễ dàng hơn.

 Mã nguồn C# đợc dịch ra ngôn ngữ trung gian IL, trong khi mã nguồn C++ đợc dịch ra mã máy nên không độc lập với nền nh C# Các thành phần của một ứng dụng đợc đóng gói trong một assembly cùng với các thông tin metadata về ứng dụng, nó cho phép CLR nạp đủ các thành phần của một ứng dụng C# vào chạy Đối với C++, các thành phần chỉ đợc định nghĩa lỏng lẻo trong các file h, tuy nhiên việc mất mát các file h cũng rất hay xảy ra, khi đó không dịch đợc chơng trình C++ Khác biệt trên đã chứng tỏ một điều: một khi ứng dụng C# đã chạy thì nó luôn chạy.

 Việc đa một ứng dụng C# vào thực thi cần nhiều thao tác hơn ứng dụng C++ nên cần nhiều thời gian hơn, khó phù hợp với các máy có cấu hình thÊp.

 Chơng trình C# có khả năng bắt các lỗi runtime và xử lí hơn là chỉ trả về mã lỗi nh C/C++.

Các câu lệnh của C# rất giống với C/C++, tuy nhiên cũng có thể kể ra một số khác biệt:

 Từ khoá new có nghĩa là tạo ra một bản copy của một kiểu dữ liệu hay đối tợng Đối tợng sẽ đợc cấp phát ở vùng heap nều nó là kiểu tham biến, cấp phát ở vùng stack nếu là kiểu tham trị.

 Tất cả các câu lệnh liên quan đến kiểm tra lô - gíc đều cần một biến kiểu boolean và không thể chuyển kiểu từ boolean sang int hay ngợc lại.

 C# có thêm câu lệnh foreach nhằm liệt kê các thành phần trong một tập hợp để thực hiện phép lặp.

 Các từ khoá checked và unchecked trong C# đợc sử dụng để kiểm tra xem những thao tác số học có bị tràn số hay không.

 Định nghĩa lại phép gán không đợc khuyến khích trong C#.

I.3 Về tổ chức chơng trình

C# không có các file header, tất cả các mã đều phải viết trong một lớp hay đơn vị tơng đơng và thuộc về lớp đó C# không yêu cầu thứ tự khai báo, định nghĩa các biến, các lớp.

Tuy nhiên trong C# cũng không có một số tính năng thuận tiện có trong C++:

 hàm hằng, toán tử phạm vi, tham biến hằng, tham biến ngầm định.

Sự khác biệt giữa C# và Java

C# và Java đều là những ngôn ngữ hoàn toàn hớng đối tợng nên chắc chắn chúng phải có nhiều điểm giống nhau, tuy nhiên cũng có tớng ứng những điểm khác nhau Khác nhau rõ nhất là khác biệt về nền C# chạy trên nền NET còn Java chạy trên nền máy ảo Java.

II.1 Về kiểu dữ liệu

C# có nhiều kiểu dữ liệu nguyên thuỷ hơn Java Bảng sau đây sẽ tổng kết các kiểu trong Java và các kiểu tơng ứng trong C# Trong Java, các kiểu nguyên thuỷ đợc phân tách theo các lớp lốt ( wrapper class) của nó, ví dụ : kiểu integer thuộc về lớp Int Tuy nhiên trong C#, những kiểu nguyên thuỷ cũng đều đợc kế thừa từ lớp object, có nghĩa là kiểu int cũng tơng đơng với lớp Int Do vậy mà trong C# có thể viết nh sau :

5 ở đây là một hằng số nguyên nhng cũng đợc coi là một đối tợng Int Nếu viết nh vậy trong Java sẽ có lỗi, trong Java phải viết nh sau:

Bảng so sánh các kiểu dữ liệu giữa Java và C#:

Java và C# đều gồm 2 loại kiểu dữ liệu tham trị và tham biến Tuy nhiên trong C# hỗ trợ kiểu struct thuộc loại tham trị còn Java thì không Do đó, trong C# chúng ta có thể định nghĩa thêm các kiểu tham trị, còn Java thì chỉ có các kiểu tham trị sẵn có, các kiểu dữ liệu ngời dùng định nghĩa ra đều là kiểu tham biến hay đối tợng thông qua định nghĩa lớp.

II.2 Về truy cập thành phần

Ngoài các thuộc tính truy cập nh public, private, protected, C# còn thêm vào thuộc tính internal Những thành phần có thuộc tính Internal sẽ đợc truy cập từ những lớp khác trong cùng một project hay chính xác hơn là trong cùng một assembly.

II.3 Các tham số ref và out

Trong Java, các kiểu dữ liệu tham trị thì luôn đợc truyền theo kiểu tham trị trong lời gọi hàm Tuy nhiên, trong C# vẫn cho phép các kiểu tham trị truyền theo kiểu tham biến trong lời gọi hàm bằng khai báo từ khoá ref đứng trớc tham số Từ khoá out cũng có chức năng nh từ khoá ref, tuy nhiên tham số dùng với từ khoá out không cần phải khởi tạo giá trị trớc khi gọi.

Interface trong Java có thể có hằng số còn trong C# thì không Khi thực thi mộtInterface, C# cũng cấp lời gọi tờng minh thực thi Interface Điều này cho phép một class thực thi 2 Interface từ 2 nguồn khác nhau có cùng tên các thành phần ( vấn đề này đã từng đợc coi nh góc tối tăm nhất của C++ trong thực hiện thừa kế , dẫn theo sách “Lập trình C++” của Ngô Trung Việt).

II.5 Về 2 từ khoá khai báo import và using

Trong Java khai báo import dùng để định vị một gói th viện vào chơng trình nh kiểu th viện.Trong C#, từ khoá using dùng để báo hiệu cho chơng trình dịch có sử dụng th viện đó và ghi vào trong assembly, còn th viện đó ở dạng th viện động, sẽ đợc load vào chơng trình bởi CLR sau khi đọc metadata lúc thực hiện chơng trình

Tuy nhiên, trong C# có một thiếu sót mà đây lại là điểm mạnh của Java đó là các applet Applet thực sự là một ứng dụng trên Web, nó đợc viết từ một nơi nào đó nhng lại có thể chạy trên một máy khách bất kì, làm giảm thời gian truyền trên mạng nhng lại thực hiện đợc nhiều công việc phức tạp nh xử lí âm thanh, hình ảnh, đa luồng ngay trên một trang Web Tuy nhiên nó lại không an toàn Applet đó có thể lấy cắp các thông tin trên máy khách rồi truyền đi Do đó, C# đã không hỗ trợ Applet, thay vào vào đó là ứng dụng Web kiểu mới dựa trên công nghệ ASP, tất cả các ứng dụng đều đợc chạy trên server, các trang Web chỉ đóng voi trò giao tiếp với ngời dùng mà thôi.

Ngoài ra trong Java, tất cả các công việc không chắc không có lỗi nh vào ra, độc file… Vì thì phải dùng cặp try – catch để bắt lỗi Trong C# không bắt buộc lập trình viên phải thực hiện try – catch ở bất kì tình huống nào Điều này có nghĩa là,ngời lập trình C# phải cẩn thận hơn trong lập trình.

Sự khác biệt giữa C# và VB 6.0

VB 6.0 và C# thuộc hai kiểu ngôn ngữ khác nhau VB 6.0 là lập trình hớng sự kiện, chỉ có một ít tính chất lập trình hớng đối tợng trong khi C# hoàn toàn hớng đối tợng Do đó, VB và C# khác nhau gần nh hoàn toàn Rất khó tìm đợc sự tơng đồng nào giữa C# và VB Vb chỉ phù hợp cho các dự án dựa trên Windows nhỏ, nhanh Nói chung định dạng ngôn ngữ C# đơn giản còn VB 6.0 rất rờm rà VB vẫn tồn tại cặp Begin – End, For- to, trong khi C# đã dơn giản đi nhiều, ngay cả For each trong C# thì trong VB phải có cách trống giữa For và each Điều này làm giảm năng suất lập trình rất mhiều VB cũng nh C++, không có một nền tách biệt với hệ điều hành, chạy thẳng trên Windows, sử dụng th viện của Windows nên rất phụ thuộc máy Hệ thống th viện của VB thì nhỏ, thờng không đáp ứng những nhu cầu ngày càng tăng của ngời lập trình Về kiểu dữ liệu, do VB không phải là hớng đối tợng nên khác hoàn toàn với kiểu dữ liệu trong C#, kiểu dữ liệu trong VB vẫn thiên về những ngôn ngữ phi đối t- ợng trớc đây nh Pascal Nói tóm lại, C# hoàn toàn vợt trội so với VB

Trong suốt bản báo cáo này, chúng em đã trình bày một vài đặc điểm cũng nh khả năng của C#, cụ thể là các đặc điểm về hệ thống nền NET cùng với ngôn ngữC#, các khả năng của C# trong các lĩnh vực đồ hoạ, thực hiện tính toán song song, lập trình mạng Chúng em cững đã đa ra một vài so sánh, nhận xét về C# trong sự tơng quan với các ngôn ngữ khác Có thể thấy rằng, C# là ngôn ngữ hiện đại, đơn giản,song có khả năng cao trong việc phát triển các dự án phần mềm C# có đầy đủ các tính năng tốt của các ngôn ngữ trớc đó đồng thời hạn chế đi nhiều lỗi mà các ngôn ngữ trớc mắc phải C# mới ra đời đợc 3 năm, nó là ngôn ngữ còn đang trong giai đoạn phát triển để hoàn thiện, vào điểm này, khó có thể đánh giá toàn bộ các u nhợc điểm của C# Trong tơng lai, C# có lẽ sẽ trở thành ngôn ngữ lập trình thông dụng nhất.Chúng em xin kết thúc đề tài tại đây Chúng em xin chân thành cảm ơn thày giáoNguyễn Ngọc Bình đã hớng dẫn chúng em tiếp cận và thực hiện đề tài này

Giới thiệu ngôn ngữ lập trình C# Tài liệu tham khảo

Ngày đăng: 04/07/2023, 06:38

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN

w