Ngôn ngữ lập trình C#

Tài liệu Ngôn ngữ lập trình C#: ... Ebook Ngôn ngữ lập trình C#

doc81 trang | Chia sẻ: huyen82 | Lượt xem: 2115 | Lượt tải: 0download
Tóm tắt tài liệu Ngôn ngữ lập trình C#, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
MôC lôc Danh s¸ch c¸c h×nh vÏ H×nh 1 KiÕn tróc nÒn .NET 9 H×nh 2 CÊu tróc CLR 11 H×nh 3 T« mµu b»ng bót vÏ Gradient tuyÕn tÝnh 21 H×nh 4 §­êng BÐzier ®­îc t« bëi bót phñ Gradient 22 H×nh 5 ChuyÓn ®æi ®å thÞ 22 H×nh 6 Co gi·n vïng ¶nh 23 H×nh 7 C¸c møc ®é trong suèt cña mµu nÒn 23 H×nh 8 HÖ trôc to¹ ®é cña GDI+ 25 H×nh 9 DÞch chuyÓn hÖ to¹ ®é 26 H×nh 10 Vßng ®êi cña mét luång 36 H×nh 11 Vßng lu©n phiªn thùc hiÖn luång 36 H×nh 12 Minh ho¹ so¹n th¶o trong WordPad 42 H×nh 13 M· cña v¨n b¶n ®äc b»ng NotePad 43 H×nh 14 M· cña v¨n b¶n Word ®äc b»ng NotePad 43 H×nh 15 T¹o v¨n b¶n HTML trong NotePad 44 H×nh 16 CÊu tróc cña XML 48 H×nh 17 Khai b¸o thµnh phÇn trong XML 49 H×nh 18 Minh häa cÊu tróc c©y cña vÝ dô 51 H×nh 19 KÕt qu¶ ch­¬ng tr×nh t¹o tµi liÖu trªn IE 6.0 54 H×nh 20 KÕt qu¶ vÝ dô Serializing trªn IE 6.0 58 Danh s¸ch c¸c thuËt ng÷ viÕt t¾t IE 6.0 = Internet Explorer 6.0 CLS = Common Language Spcification CLR = Common Language Runtime IDE = Integrated Development Environment API = Application Programming Interface VB = Visual Basic VC = Visual C VS = Visual Studio XML = Extensible Markup Language MSIL = IL = Microsoft Intermediate Language COM = Component Object Model IDL = Interface Definition Language DLL = Dynamic Link Library GC = Garbage Collection JIT = Just In Time compiler ADO = ActiveX Data Object MS = Microsoft SQL = Structured Query Language GDI = Graphic Device Independence WMF = Window MetaFile EMF = Enhanced MetaFile CPU = Central Processing Unit RTF = Rich Text Format HTML = Hyper Text Markup Language SGML = Standard Generalized Markup Language Giíi thiÖu ®Ò tµi Trong nhiÒu n¨m, c¸c lËp tr×nh viªn C vµ C++ lu«n ph¶i ®èi mÆt víi nh÷ng vÊn ®Ò ®au ®Çu nh­: sö dông con trá, qu¶n lÝ bé nhí, truyÒn tham trÞ, tham biÕn, xö lý danh s¸ch, x©y dùng th­ viÖn, ®a kÕ thõa, x©y dùng giao diÖn th©n thiÖn víi ng­êi dïng… V× vËy hä lu«n mong muèn, t×m kiÕm mét ng«n ng÷ thay thÕ cã kh¶ n¨ng còng nh­ tÝnh uyÓn chuyÓn m¹nh nh­ C vµ C++ h¬n n÷a l¹i ®¬n gi¶n h¬n. Vµo gi÷a nh÷ng n¨m 90, thÕ giíi lËp tr×nh cã sù thay ®æi lín víi sù bïng næ Internet ( Internet Boom ) vµ sù ra ®êi cña ng«n ng÷ lËp tr×nh Java. Ngay tõ khi ra ®êi, Java ®· cho thÊy kh¶ n¨ng to lín cña nã trong viÖc ph¸t triÓn c¸c øng dông trªn internet. H¬n n÷a Java cßn thnµh c«ng víi tuyªn bè “write once, run anywhere” cè thÓ t¹m dich lµ : viÕt mét lÇn, ch¹y trªn mäi nÒn. Thµnh c«ng ®ã xuÊt ph¸t tõ ý t­ëng t¸ch rêi m· khi biªn dÞch ch­¬ng tr×nh vµ m· khi ch¹y ch­¬ng tr×nh, ®©y lµ ®iÓm kh¸c biÖt lín so víi nh÷ng ng«n ng÷ lËp tr×nh C hay C++. Java ®­a ra mét kh¸i niÖm míi : m¸y ¶o. M¸y ¶o thùc hiÖn c¸c c«ng viÖc nh­ biªn dÞch ra m· m¸y, qu¶n lÝ bé nhí… hay nãi c¸ch kh¸c, m¸y ¶o ®ãng vai trß giao tiÕp gi÷a øng dông Java vµ m«i tr­êng ( hÖ ®iÒu hµnh, hay phÇn cøng) lµm cho øng dông Java ®éc lËp víi m«i tr­êng. Tuy nhiªn tèc ®é ph¸t triÓn Java l¹i chËm dÇn, vµ kh«ng thÓ ®Êp øng ®­îc nh÷ng ®ßi hái ngµy cµng cao cña ng­êi dïng. C¸c h·ng ph¸t triÓn Java chËm ®­a ra mét m«i tr­êng tÝch hîp IDE phôc vô cho ph¸t triÓn c¸c dù ¸n phÇn mÒm. ViÖc lËp tr×nh c¸c øng dông trªn Windows b»ng Java kh«ng thuËn tiÖn, Java cã nhiÒu h¹n chÕ trong viÖc giao tiÕp víi c¸c ng«n ng÷ kh¸c nh­ C++, Visôal Basic…Java kh«ng cã sù ph¸t triÓn ®ång nhÊt theo xu h­íng thuËn tiÖn cho ng­êi sö dông, ph¶i mÊt nhiÒu n¨m Java míi hç trî ®­îc ®iÒu khiÓn Mouse – wheel, khã sö dông th­ viÖn API cña hÖ ®iÒu hµnh, phiªn b¶n Visual J++ cña Microsoft ph¸t triÓn th× l¹i mang nhiÒu nÐt kh«ng gièng víi nguyªn b¶n. Windows XP ra ®êi víi tuyªn bè kh«ng hç trî m¸y ¶o Java, kh«ng tÝch hîp m¸y ¶o Java vµo tr×nh duyÖt IE 6.0 ®· lµm uy tÝn cña Java suy gi¶m nÆng nÒ. Cuèi cïng th× ng«n ng÷ mµ c¸c lËp tr×nh viªn mong ®îi còng xuÊt hiÖn, ®¸nh dÊu chÊm hÕt cho cuéc t×m kiÕm ng«n ng÷ lËp tr×nh kÐo dµi nhiÒu n¨m cña c¸c lËp tr×nh viªn. §­îc b¾t ®Çu nghiªn cøu tõ n¨m 1997, vµo n¨m 2001, Microsoft giíi thiÖu mét platform míi --.Net, ®i cïng víi nã lµ mét ng«n ng÷ míi - C#. C# ®­îc coi nh­ ng«n ng÷ mang tÝnh c¸ch m¹ng cña Microsoft. Dùa trªn kinh nghiÖm cña c¸c ng«n ng÷ tr­íc ®ã nh­ C, C++ vµ VB, C# ®­îc thiÕt kÕ nh»m sö dông ®¬n gi¶n, hoµn toµn h­íng ®èi t­îng. Víi sù tÝch hîp C# víi VS. Net, viÖc ph¸t triÓn c¸c øng dông Windows vµ Web nhanh vµ ®¬n gi¶n. Cã thÓ truy cËp vµo c¸c th­ viÖn líp cña .Net, C# hç trî ph¸t triÓn c¸c øng dông ASP.Net vµ dÞch vô Web. Bªn c¹nh ®ã, C# t¨ng c­êng n¨ng suÊt lËp tr×nh b»ng viÖc xo¸ bá ®i nh÷ng lçi th«ng th­êng cã trong C vµ C++. Java thµnh c«ng nhÊt trªn 2 lÜnh vùc: lËp tr×nh c¸c øng dông trªn server vµ trong gi¶ng d¹y khoa häc tÝnh trong c¸c tr­êng häc. C# còng cã kh¶ n¨ng v­ît tréi Java trªn hai lÜnh vùc ®ã. Trong ®Ò tµi nµy, chóng em kh«ng thÓ tr×nh bµy hÕt mäi vÊn ®Ò liªn quan ®Õn ng«n ng÷ C#, chóng em chØ xin giíi thiÖu s¬ bé vÒ .NET vµ C# cïng víi mét sè vÊn ®Ò n©ng cao trong ng«n ng÷ C# nh­ sau: Giíi thiÖu s¬ bé vÒ nÒn .NET vµ ng«n ng÷ C# §å ho¹ trong C# §a luång trong C# XML vµ C# LËp tr×nh m¹ng trong C# Mét vµi so s¸nh C# víi c¸c ng«n ng÷ kh¸c Trong ®Ò tµi nµy, chóng em kh«ng d¸m ch¾c mäi tr×nh bµy, ®¸nh gi¸ lµ chÝnh x¸c, x¸c ®¸ng. Trong khi lµm ®Ò tµi cã mét sè thuËt ng÷ Anh khã chuyÓn t¶i ®óng nghÜa sang tiÕng ViÖt nªn ®­îc gi÷ nguyªn. Chóng em kÝnh mong thÇy th«ng c¶m vµ gãp ý söa ch÷a nh÷ng ®iÓm ch­a tèt trong b¸o c¸o. PhÇn I: Giíi thiÖu s¬ bé vÒ nÒn .NET vµ ng«n ng÷ C# NÕu nh­ Java ra ®êi, næi tiÕng víi tuyªn bè: “ write once, run anywhere”, th× ngay tõ khi chµo ®êi, C# vµ .NET ®­îc c¸c nhµ thiÕt kÕ g¾n víi tuyªn bè: “ Every language, one platform”, cã thÓ t¹m dÞch lµ: mäi ng«n ng÷ ®Òu ch¹y trªn mét nÒn. NÒn ®ã chÝnh lµ .NET ( .NET Framework). VËy .NET lµ g× ? Chóng ta sÏ cïng nhau t×m hiÓu vÒ .NET qua c¸c vÊn ®Ò sau : Giíi thiÖu chung vÒ nÒn .NET Nh÷ng ®Æc ®iÓm cña nÒn .NET Nh÷ng thµnh phÇn cña .NET I. 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ã ch­a 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: 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. Gi¶m thiÓu tèi ®a xung ®ét gi÷a c¸c version cña mét phÇn mÒm §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 : NÒn .NET: mét nÒn cho phÐp ph¸t triÓn c¸c øng dông 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. 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 ®Ò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 tr­ng cña nÒn .NET Nh÷ng ®Æc tr­ng 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 tr­ng 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 ch­a 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. I.3.4. Hç trî phiªn b¶n 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. I.4.1. CLR 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 Memory Management Including Garbage Collection Execution Support CIL Compiler Common Type system Security C I L Class Loader M A C H I N E C O D E H×nh 2 CÊu tróc CLR 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 l­u 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. Lo¹i tham biÕn: kiÓu tham biÕn l­a gi÷ ®Þa chØ chØ tíi mét vïng d÷ liÖu, chóng ®­îc cÊp ph¸t ë vïng nhí Heap. Nh÷ng d÷ liÖu kiÓu nµy th­êng lµ c¸c biÕn ®èi t­îng. CLS ( common language specification) lµ mét tËp hîp c¸c ®Æc ®iÓm ng«n ng÷ mµ tÊt c¶ c¸c ng«n ng÷ lËp tr×nh trªn .NET ph¶i tu©n theo, nã còng bao gåm c¸c kiÓu d÷ liÖu vµ c¸c qui c¸ch trong hÖ thèng kiÓu th«ng th­êng. Nh÷ng ng­êi muèn ph¸t triÓn mét ng«n ng÷ trªn .NET th× còng ph¶i dùa theo CLS ®Ó x©y dùng ch­¬ng tr×nh dÞch gäi lµ ch­¬ng tr×nh dÞch CLS . Ng«n ng÷ trung gian IL ®­îc dÞch ra tõ m· nguån cña mét ng«n ng÷ lËp tr×nh cÊp cao b»ng mét ch­¬ng tr×nh dÞch CLS, ng«n ng÷ trung gian IL sau ®ã ®­îc CLR dÞch l¹i mét lÇn n÷a ra m· m¸y ®Ó thùc thi. I.4.4. Th­ viÖn líp c¬ së cña .NET .NET cã mét th­ viÖn ®è sé nh÷ng kiÓu d÷ liÖu cã thÓ sö dông l¹i, ®­îc tÝch hîp chÆt chÏ víi CLR. Th­ viÖn líp nµy hoµn toµn h­íng ®èi t­îng, cung cÊp nh÷ng kiÓu d÷ liÖu mµ chóng ta cã thÓ sö dông rÊt nhiÒu chøc n¨ng tõ ®ã. Nhê sö dông th­ viÖn líp c¬ së chóng ta cã thÓ ph¸t triÓn c¸c kiÓu øng dông sau: øng dông vµo ra Console Nh÷ng øng dông Windows víi giao diÖn ®å ho¹ Nh÷ng øng dông ASP.NET DÞch vô Web C¸c th­ viÖn Khi muèn lËp tr×nh trªn Windows chóng ta cã thÓ sö dung c¸c líp Form, Button, CheckBox, Text… ®Ó ph¸t triÓn c¸c giao diÖn ®å ho¹. Khi muèn ph¸t triÓn mét øng dông Web, chóng ta cã thÓ sö dông c¸c líp Web Forms. TÊt c¶ c¸c ng«n ng÷ cña .NET ®Òu sö dông th­ viÖn nµy, ®iÒu nµy lµm cho viÖc sö dông ®a ng«n ng÷ còng dÔ dµng h¬n. I.4.5. Assembly vµ metadata NÕu chóng ta muèn tr×nh bµy kÜ vÒ assembly vµ metadata th× cÇn ph¶i cã mét ®Ò tµi chuyªn vÒ m¶ng nµy, trong giíi h¹n ®Ò tµi nµy, chóng em chØ xin tr×nh bµy mang tÝnh kh¸i niÖm vÒ hai vÊn ®Ò trªn. Assembly cã thÓ hiÓu nh­ lµ mét gãi c¶ m· ch­¬ng tr×nh, c¸c thµnh phÇn, c¸c tµi nguyªn. Mét assembly bao gåm th«ng tin metadata, m· ch­¬ng tr×nh ë d¹ng IL, c¸c file tµi nguyªn vÝ dô nh­ c¸c file ¶nh, ©m nh¹c, c¸c th­ viÖn thµnh phÇn. Metadata lµ tËp hîp d÷ liÖu ë d¹ng nhÞ ph©n diÔn t¶ c¸c thµnh phÇn cña ch­¬ng tr×nh. Metadata ®­îc l­u tr÷ ë file cã thÓ thùc thi ( executable hay .exe , .dll) cïng víi m· IL cña ch­¬ng tr×nh. Metadata chøa nh÷ng lo¹i d÷ liÖu cô thÓ sau: Tªn assembly Sè hiÖu phiªn b¶n  Culture : th«ng tin vÒ lo¹i ng«n ng÷ mµ assembly hç trî Th«ng tin vÒ strong name Danh s¸ch tÊt c¶ c¸c file ®­îc ®ãng gãi Th«ng tin vÒ tham chiÕu kiÓu d÷ liÖu: CLR sö dông th«ng tin nµy ®Ó t×m ra nh÷ng file ®Þnh nghÜ kiÓu d÷ liÖu ®ã. Th«ng tin phôc vô cho tham chiÕu ®Õn c¸c assembly kh¸c CLR hoµn toµn dùa nh÷ng th«ng tin nµy ®Ó ®iÒu khiÓn øng dông. Assembly vµ metadata ®­îc t¹o ra ngay khi ta biªn dÞch m· nguån I.4.6. Ch­¬ng tr×nh dÞch Just in time Ch­¬ng tr×nh dÞch Just In Time lµ n»m trong CLR, cã nhiÖm vô chuyÓn m· IL sang m· m¸y thÝch hîp. Trong .NET cã 3 lo¹i ch­¬ng tr×nh dÞch JIT: Pre-JIT: lo¹i JIT nµy dÞch ngay toµn bé m· IL sang m· m¸y khi nã ®­îc gäi tíi. Econo-JIT: lo¹i nµy sö dông cho c¸c hÖ thèng h¹n chÕ bé nhí, nã dÞch m· IL sang m· m¸y tõng bit mét, nh÷ng m· m¸y sau khi ®­îc dÞch vµ ®­a vµo thùc thi nã cßn ®­îc ®Ó ë vïng nhí ®Öm, nÕu hÕt vïng nhí ®Öm JIT sÏ xo¸ c¸c m· m¸y nµy. Normal JIT: ®©y lµ lo¹i ngÇm ®Þnh, dÞch m· IL chØ khi nã ®­îc gäi tíi, m· m¸y sau khi dÞch sÏ ®­îc ®­a vµo thùc thi ®ßng thêi ®­îc ®Æt vµo trong bé nhí ®Öm. I.4.7. Qu¶n lÝ bé nhí ( Garbage Collection ) Nh÷ng ng­êi lËp tr×nh th­êng gÆp nhiÒu khã kh¨n khi gi¶i quyÕt vÊn ®Ò cÊp ph¸t bé nhí, rß rØ bé nhí, c«ng viÖc nµy lµm gi¶m n¨ng suÊt lËp tr×nh. §Ó gi¶i quyÕt vÊn ®Ò 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Ï th­c 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. I.4.8. Vßng ®êi cña m· 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 _CorExeMain thùc thi. 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#. II.2.1. C¸c to¸n tö 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Þ l­a tr÷ trùc tiÕp d÷ liÖu cña nã, tr¸i l¹i biÕn tham biÕn l­a 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++. II.2.3. C¸c c©u lÖnh 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 class HelloMessage { public string GetMessage() { return "Hello, world"; } } } Namespace 2: using Microsoft.CSharp.Introduction; class Hello { static void Main() { HelloMessage m = new HelloMessage(); System.Console.WriteLine(m.GetMessage()); } } Trong mét namespace cã thÓ lång mét hay nhiÒu namespace kh¸c, vÝ dô: namespace Microsoft { namespace CSharp { namespace Introduction {....} } } 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. Internal: nh÷ng ®èi t­îng ®­îc ®Þnh nghÜa trong mét assembly ( c¸c file ®Þnh nghÜa chóng cïng n»m trong 1 assembly) cã thÓ truy cËp nh÷ng thµnh phÇn Internal cña nhau. Nh÷ng thµnh phÇn Internal lµ nh÷ng thµnh phÇn kh«ng khai b¸o thuéc tÝnh truy cËp. Private: thµnh phÇn nµy chØ ®­îc truy cËp tõ nh÷ng thµnh phÇn trong cïng 1 líp. CÊu tróc ( struct): chóng ta cã thÓ x©y dùng mét lo¹i struct n»m ngoµi c¸c líp vµ n»m trong 1 namespace nªn cã thÓ coi nã lµ mét ®¬n vÞ ch­¬ng tr×nh ngang víi class. Struct còng kh¸ gièng víi class khi nã còng cã c¸c biÕn d÷ liÖu thµnh phÇn víi thuéc tÝnh truy cËp cña chóng, hµm khëi t¹o. Tuy nhiªn struct l¹i lµ d÷ liÖu kiÓu tham trÞ cßn class lµ d÷ liÖu kiÓu tham biÕn, struct kh«ng cho phÐp kÕ thõa. Giao diÖn ( Interface ): ng«n ng÷ C++ cho phÐp ®a thõa kÕ, tõ ®ã sinh ra c¸c nhËp nh»ng, r¾c rèi khi truy cËp c¸c thµnh phÇn cña c¸c líp cha. Trong C# kh«ng cho phÐp chóng ta thùc hiÖn ®a thõa kÕ tõ nhiÒu líp. Tuy nhiªn ®Ó thùc hiÖn ®a thõa kÕ, C# t¹o ra mét ®¬n vÞ ch­¬ng tr×nh míi lµ Interface, thay v× khai b¸o thõa kÕ tõ nhiÒu líp, chóng ta cã thÓ khai b¸o thõa kÕ tõ mét líp vµ thùc thi nhiÒu Interface. Qua ®ã, chóng ta còng cã thÓ thùc hiÖn ®a kÕ thõa. Mét Interface cã thÓ chøa c¸c ph­¬ng thøc, thuéc tÝnh, sù kiÖn…, vÝ dô: interface IExample { string this[int index] { get; set; } event EventHandler E; void F(int value); string P { get; set; } } public delegate void EventHandler(object sender, Event e); Mäi øng dông trªn C# ®Òu cã hµm main. Hµm main chÝnh lµ ®iÓm vµo cña ch­¬ng tr×nh (entry point), ch­¬ng tr×nh b¾t ®Çu tõ hµm main vµ kÕt thóc ë ®©y. Trong hµm main chóng ta cã thÓ khëi t¹o c¸c ®èi t­îng ( trong lËp tr×nh giao diÖn Windows) hay gäi c¸c hµm kh¸c thùc thi ( trong lËp tr×nh Console ). Hµm main ph¶i lµ static vµ x©y dùng trong mét líp, cã thÓ tr¶ l¹i gi¸ trÞ Int hay kh«ng tr¶ vÒ gi¸ trÞ. II.3. C# vµ nh÷ng vÊn ®Ò n©ng cao II.3.1. C# víi c¬ së d÷ liÖu C# cho phÐp thao t¸c thuËn tiÖn víi c¸c lo¹i c¬ së d÷ liÖu SQL Server 2000, MS access, Oracle,… b»ng th­ viÖn líp ADO.NET. ADO.NET lµ phiªn b¶n míi nhÊt cña chiÕn l­îc truy cËp c¬ së d÷ liÖu v¹n n¨ng cña Microsoft. Th­ viÖn líp ADO.NET chia thµnh 2 lo¹i lµ líp kÕt nèi vµ líp kh«ng kÕt nèi. Líp kÕt nèi lµ tr×nh ®iÒu khiÓn kÕt nèi c¬ së d÷ liÖu (Data Provider) cô thÓ, cã nghÜa lµ chóng ta ph¶i sö dông mét .NET Data Provider mµ chóng hç trî c¬ së d÷ liÖu cÇn lµm viÖc. Trong khi ®ã líp kh«ng kÕt nèi sö dông bÊt k× .NET data Provider nµo. Khi chóng ta cÇn thiÕt ph¶i truy cËp, xö lÝ d÷ liÖu nguån víi c¸c thao t¸c select, insert, delete, update chóng ta ph¶i sö dông líp kÕt nèi, ng­îc l¹i nÕu chØ thao t¸c trªn d÷ liÖu t¹m thêi th× dïng líp kh«ng kÕt nèi. Lo¹i líp kÕt nèi gåm 4 líp sau: Connection: Líp kÕt nèi c¬ së d÷ liÖu. DataAdapter: Líp chøa d÷ liÖu. Command: líp chøa lÖnh. DataReader: Líp ®äc d÷ liÖu. Lo¹i líp kh«ng kÕt nèi gåm c¸c líp sau: Líp DataSet: DataSet n¾m gi÷ Tables vµ Relations Líp DataTable: DataTable n¾m gi÷ c¸c Rows, Column Líp DataView: DataView t¹o nªn c¸c view cho d÷ liÖu II.3.2. C# víi Internet Tõ gi÷a nh÷ng n¨m 90, thÕ giíi lËp tr×nh cã sù thay ®æi tõ lËp tr×nh øng dông trªn c¸c m¸y riªng lÎ chuyÓn sang lËp tr×nh c¸c øng dông trªn Internet. C¸c ch­¬ng tr×nh øng dông trªn Web cã c¸c ­u ®iÓm nh­ : chi phÝ thÊp, truy cËp thuËn tiÖn tõ c¸c n¬i kh¸c nhau…§èi víi c¸c site tÜnh (static site) dï lµ ®¬n gi¶n nhÊt còng cÇn ph¶i lËp tr×nh ®Ó qu¶n lÝ Web Form. Líp HttpHandler cung cÊp nh÷ng ph­¬ng thøc ®¬n gi¶n, râ rµng ®Ó qu¶n lÝ c¸c Web Form. §èi víi c¸c site ®éng (Dynamic site), ASP.NET lµ th­ viÖn hoµn h¶o ®Ó t¹o ra nh÷ng trang Web cã néi dung thay ®æi theo thêi gian ®Æc biÖt lµ th­¬ng m¹i ®iÖn tö. §èi víi m¹ng ngang hµng Peer-To-Peer, C# cã c¸c c«ng cô m¹nh ®Ó t¹o nªn c¸c hÖ thèng m¹ng ngang hµng cã kh¶ n¨ng chia sÎ c¸c tµi nguyªn. PhÇn II: §å häa trong C# Đồ họa là một phần không thể thiếu trong các ngôn ngữ lập trình cũng như các bộ công cụ phát triển nhất là trong thời đại các giao diện đồ họa người sử dụng phát triển mạnh như hiện nay. Thực tế là hiện nay giao diện đẹp và thân thiện đóng góp một phần không nhỏ trong thành công của các phần mềm. Trong phần này chúng ta sẽ khảo sát các công cụ đồ họa GDI+ của C# và tổng quát hơn là của môi trường phát triển ứng dụng .NET. I. 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. II. 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: Hình học vector 2D Hình ảnh. Typography. Sau đây chúng ta sẽ xem xét lần lượt từng lớp này: II.1. §å häa Vector 2D Đồ 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. II.2. H×nh ¶nh 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÷ 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. III. 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. IV. Mét sè ®iÓm míi trong GDI+ IV.1. Bót vÏ Gradient 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 IV.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­î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 IV.6. §æ bãng Alpha 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 V. Thay ®æi trong m« h×nh lËp tr×nh V.1. Ng÷ c¶nh thiÕt bÞ, Handles và c¸c ®èi t­î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ô 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÷ 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ớp Graphics 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ẽ. VI. Giíi thiÖu c¸c ®èi t­îng ®å häa c¬ b¶n trong GDI+ VI.1. §å häa Vector 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: Lines Rectangles Ellipses Arcs Polygons Cardinal splines Bézier splines 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 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: Windows Metafile (WMF) Enhanced Metafile (EMF) EMF+ 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) { Graphics myGraphics = e.Graphics; 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); PhÇn III: §a luång trong C# §a luång ( multithreading) d­êng nh­ lµ mét thuËt ng÷ míi, tuy vËy nã l¹i rÊt quen thuéc víi chóng ta nhÊt lµ trong cuéc sèng h»ng ngµy. Mét vÝ dô ®iÓn h×nh cña ®a luång mµ ai còng cã thÓ nhËn ra lµ ho¹t ®éng cña c¸c c¬ quan trong c¬ thÓ. C¬ thÓ chóng ta cã thÓ thùc hiÖn cïng mét lóc v« sè c«ng viÖc nh­ h« hÊp, tuÇn hoµn, tiªu ho¸… C¸c ho¹t ®éng nµy diÔn ra ®ång thêi. Chóng ta còng cã thÓ t×m thÊy h×nh ¶nh cña ®a luång trong vÝ dô kh¸c lµ ho¹t ®éng cña mét chiÕc xe m¸y. Mét chiÕc xe m¸y cã thÓ thùc hiÖn nhiÒu ®éng t¸c nh­ lµ rÏ, t¨ng tèc, nh¸y ®Ìn… ®ång thêi. Trong c¸c phÇn sau, chóng ta sÏ t×m hiÓu ®a luång trong thùc hiÖn ch­¬ng tr×nh m¸y tÝnh. I. 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: I.1. §a nhiÖm ( multitasking ) 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 nh­ng 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. I.2. §a luång ( multitasking) 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. Nh­ng 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. II. §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íp ThreadPool 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 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: Classes Class M« t¶ 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 RegisterWaitForSingleObject. SynchronizationLockException 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, Structure: Structure M« t¶ 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. Delegates Delegate M« t¶ ThreadStart M« t¶ ph­¬ng thøc c¸i mµ b¾t ®Çu víi Thread class ThreadExceptionEventHandler 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 Timer Enumeration: Enumeration M« t¶ 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. Vi dô: 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 ch­a 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 OutOfMemoryException 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 ph­ong 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 [C#] public ThreadState ThreadState {get;} (**) [C#] public bool IsAlive {get;}) (*) (*) - Thuéc tÝnh nµy cã gi¸ trÞ lµ true khi mµ luång ®· ®­îc gäi vµ ch­a chÕt ( tøc lµ ph­¬ng thøc stop cña nã ch­a ®­îc gäi vµ ph­¬ng thøc kiÓm so¸t run cña nã ch­a 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 l­u ý 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 ch­a kÕt thóc. Ph­¬ng thøc nµy còng sinh ra hai ngoai lÖ lµ ThreadSateException tøc luång ch­a b¾t ®Çu hoÆc do thêi gian lµ ©m ArgumentOutOfRangeException. Khi thùc hiÖn c¸c ph­¬ng thøc nµy th× chóng ®Òu lµm thay ®æi tr¹ng th¸i cña luång gäi tíi ThreadState.WaitSleepJoin vµ ta cÇn chó ý lµ kh«ng gäi ph­¬ng thøc nµy khi luång ®ang ë tr¹ng th¸i ThreadState.Unstarted. VÝ dô: using System; using System.Thread; class test { public static void thuyet() { Console.WriteLine(“Trangthai:”+Second.CurrentState.ThreadSate); /*sö dông thuéc tÝnh CurrentThread ®Ó tr¶ vÒ tr¹ng th¸i cña luång cña luång hiÖn thêi */ } public static void Main() { Console.WriteLine(“Luong chinh”); ThreadStart my=new ThreadStart(thuyet); Thread second=new Thread(my); second.Start(); second.Join(); Console.WriteLine(“Ket thuc:”+second.ThreadState); } } Trong ch­¬ng tr×nh trªn khi thùc hiÖn nÕu ta bá ®i dßng lÖnh second.Join() th× ch­¬ng tr×nh cho ta ®Çu ra : Luong chinh. Ketthuc:unstarted Trangthai:Running. Tuy nhiªn khi ta cho dßng lÖnh vµo th× khi ®ã luång ch­¬ng tr×nh chÝnh sÏ ®i vµo tr¹ng th¸i Thread.WaitSleepJoin vµ chê cho luång võa t¹o ra kÕt thóc míi tiÕp tôc lµm tiÕp do ®ã ®Çu ra cña ch­¬ng tr×nh trªn: Luong chinh. Trangthai:Running Ketthuc:unstarted II.2.3. Dõng mét luång §Ó dïng mét luång trong C# ta cã thÓ sö dông ph­¬ng thøc Thread.Susppend [ public void suspend();] Tuy nhiªn khi ta gäi ph­¬ng thøc nµy, hÖ thèng kh«ng thùc hiÖn ngay hµnh ®éng nµy ngay lËp tøc. Thay vµo ®ã, nã ghi nhËn mét luång ®×nh chØ võa yªu cÇu vµ chê ®îi cho ®Õn khi luång ®¹t ®Õn mét ®iÓm an toµn (safe point) tr­íc khi thùc sù ®×nh chØ luång ®ã ho¹t ®éng. Mét ®iÓm an toµn cho mét luång lµ mét ®iÓm an toµn cho gom r¸c. Ph­¬ng thøc nµy chØ sÏ kh«ng hiÖu qu¶ khi chóng ta gäi ph­¬ng thøc nµy khi mµ luång ®· bÞ dõng vµ ®Ó kh«i phôc luång bÞ ®×nh chØ ta sö dông ph­¬ng thøc Thread.Resume() ®Ó kh«i phôc l¹i ho¹t ®éng cña luång. Líp Thread cßn ®­a ra cho ta mét ph­¬ng thøc Thread.Sleep còng dïng cho môc ®Ých nh­ trªn. Ph­¬ng thøc nµy lÊy tham sè lµ thêi gian chØ ®Þnh luång sÏ dõng trong bao l©u sau ®ã kh«i phôc thùc hiÖn. §©y kh«ng ph¶i lµ sù ®Þnh thêi khãa biÓu cho luång thùc hiÖn vµ khi thùc hiÖn th× ph­¬ng thøc nµy ®­a luång vµo tr¹ng th¸i WaitSleepJoin. §Ó gäi mét luång ra khái tr¹ng th¸i WaitSleepJoin chóng ta cã thÓ sö dông ph­¬ng thøc Thread.Interrupt() ®Ó lµm luång trë l¹i ho¹t ®éng. II.2.4. Hñy mét luång Ph­¬ng thøc Thread .Abort ®Ó lµm ng­ng h¼n mét luång ®ang ho¹t ®éng, cã hai ph­¬ng thøc cho ho¹t ®éng nµy: mét lµ kh«ng ®èi sè hai lµ cã ®èi sè tuy nhiªn chóng ta th­êng sö dông ph­¬ng thøc kh«ng ®èi sè lµ chñ yÕu: public void Abort(); public void Abort(Object); Khi gäi ph­¬ng thøc nµy ®­a ra mét._.reamWriter(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); } //Close connection, stop server } finally { try { Console.WriteLine("closing..."); cnxn.Close(); } finally { server.Stop(); } } } }///:~ 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()); TcpClient client = new TcpClient(); // 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(str); } writer.WriteLine("END"); } finally { 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. I.3. Server phôc vô nhiÒu clients Ở các ví dụ trên chúng ta đã thấy được sự dể dàng trong việc tạo một socket kết nối cũng như việc thao tác trên các dòng tin StreamNetwork giống như chúng ta đang thao tác trên các dòng tin vào ra bình thường khác. Phần tiếp theo đây chúng ta sẽ xem xÐt viÖc tạo ra một server cho phép cùng lúc nhận nhiều kết nối. Và câu trả lời cho vấn đề này là multithreading mà chúng ta đã xét trong phần trước. Trong các ngôn ngữ không hç trợ trực tiếp multithreading thì mọi việc trở nên rất phức tạp. Ở trong phÇn III chóng ta đã thấy sự đơn giản của multithreading. Bởi vì tiến trình trong C# được quản lý một cách hợp lý nên việc tạo ra một server để bắt tay với nhiều client một lúc không phải là khó. Lược đồ cơ bản là tạo ra một ServerSocket đơn trong server và gọi Accept() để chờ các kết nối mới. Khi Accept() trả về, bạn có được Socket và dùng nó để tạo ra các tiến trình mới làm việc với server giống những client riêng rẽ. Sau đó lai gọi Accept() để chờ đợi những kết nối mới. using System; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading; public class MultiJabberServer { // Choose a port outside of the range 1-1024: public static readonly int PORT = 1711; public static void Main(){ new MultiJabberServer(); } public MultiJabberServer(){ TcpListener server = new TcpListener(PORT); try { server.Start(); Console.WriteLine("Started: " + server); while (true) { // Blocks until a connection occurs: TcpClient cnxn = server.AcceptTcpClient(); Console.WriteLine( "Connection accepted: "+ cnxn); new ServeOneJabber(cnxn); } } catch (Exception ex) { Console.WriteLine(ex); } finally { server.Stop(); } } } class ServeOneJabber { TcpClient cnxn; internal ServeOneJabber(TcpClient cnxn){ this.cnxn = cnxn; ThreadStart oneServer = new ThreadStart(Run); Thread svrThread = new Thread(oneServer); svrThread.Start(); } public void Run(){ try { 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); } } finally { cnxn.Close(); } } }///:~ MultiJabberServer() khởi tạo bắt đầu TcpListener và chờ đợi cho các kết nối được tạo ra. Khi kết nối được tạo ra, nó sẽ khởi tạo một đối tượng ServerOneJabber, qua đó TcpClient là đại diện cho kết nối mới. ServerOneJabber() khởi tạo chứa TcpClient cnxn là biến instance cùng tên. Tạo ra một ThreadStart đại diện và bắt đầu tiến trình mới Thread. Sự khởi tạo này thành công một cách nhanh chóng và cho phép MultiJabberServer tiếp tục lắng nghe chờ các yêu cầu kết nối khác. Phương thức ServerOneJabber.Run() là phương thức tạo một tiến trình đại diện và nó chứa đựng các nhận dạng đối với các JabberServer chỉ in ra màn hình console những gì gửi đến nó. Trách nhiệm đóng TcpClient không thuộc về MultiJabberServer mà chỉ khởi tạo nó. Đúng hơn là phương thức ServerOneJabber.Run() có sự phản hồi khi gọi TcpClient.Close() bên trong khối mệnh đề finally. Nên chú ý đến tính đơn giản của MultiJabberServer. Ngay trước khi một TcpListener được khởi tạo và AcceptTcpClient được gọi cho phép tạo ra một kết nối mới. Nhưng lúc nàygiá trị trả về (của TcpClient) được tạo ra từ sự khởi tạo của ServerOneJabber, cái mà tạo ra tiến trình mới và bắt tay kết nối. Khi kết nối kết thúc thì tiến trình này cũng bị hủy. II. 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 Web Browser, 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 HTTP GET đế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){ HttpWebRequest req = (HttpWebRequest) WebRequest.Create(args[0]); Console.WriteLine("Created, but not connected"); HttpWebResponse res = (HttpWebResponse) req.GetResponse(); Console.WriteLine("Status: " + res.StatusCode); foreach(string key in res.Headers.Keys){ Console.WriteLine("Header[{0}]:{1}", key, res.Headers[key]); } Console.WriteLine("Contents:"); StreamReader rdr = new StreamReader( res.GetResponseStream()); Console.WriteLine(rdr.ReadToEnd()); } }///:~ 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 Internet Information 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ức IHttpHandler.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(). II.3. DÞch vô Web 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ằng WebServices 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="")] 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. PhÇn VI: Mét vµi so s¸nh C# víi c¸c ng«n ng÷ kh¸c Trong phÇn nµy, chóng em sÏ ®­a ra mét vµi so s¸nh theo suy nghÜ c¸ nh©n nh»m ®­a ra nh÷ng sù kh¸c biÖt cña C# víi c¸c ng«n ng÷ kh¸c. C#, C++, Java cã thÓ coi nh­ cã chung mét nguån gèc ®ã lµ lo¹i ng«n ng÷ lËp tr×nh h­íng ®èi t­îng nªn chóng cã ®é t­¬ng ®ång víi nhau h¬n lµ t­¬ng ®ång víi c¸c ng«n ng÷ kh¸c. VB cã thÓ coi lµ Ýt t­¬ng ®ång nhÊt víi C#. I. 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. I.1. VÒ m«i tr­êng 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á nh­ng 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++. I.2. VÒ c¸c lÖnh 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++: §a thõa kÕ hµm h»ng, to¸n tö ph¹m vi, tham biÕn h»ng, tham biÕn ngÇm ®Þnh. Khëi t¹o sao chÐp Define Typedef II. 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 : Console.WriteLine(5.ToString()); 5 ë ®©y lµ mét h»ng sè nguyªn nh­ng 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: Console.WriteLine(Integer.toString(5)); 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. II.4. Giao diÖn (Interfaces) Interface trong Java cã thÓ cã h»ng sè cßn trong C# th× kh«ng. Khi thùc thi mét Interface, 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 ®ã nh­ng 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 nh­ng 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… 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. III. 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. KÕt luËn 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¸o NguyÔ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. Tµi liÖu tham kh¶o [1] Anders Hejlsberg, Scott Wiltamuth; C# Language Reference; Microsoft press [2] Adrian Turtschi; C# . N ET Developer’s Guide; Syngress [3] Eric Gunnerson; A Programmer's Introduction to C#; Apress [4] Evangelos Petroutsos; Mastering Visual Basic .Net Multithreading Tutorial; Sybex [5] Jesse Liberty; Programming C#; O'Reilly [6] Larry O’Brien, Bruce Eckel; Thingking in C#; Prentice Hall [7] MSDN Library; Microsoft press [8] Ng« Trung ViÖt; H­íng dÉn lËp tr×nh C++; NXB Giao Th«ng VËn T¶i [9] Paul Deitel; Tù häc ng«n ng÷ lËp tr×nh Java; NXB Thèng Kª [10] R. Allen Wyke; XML programming; Microsoft press Phô lôc I. M« t¶ ch­¬ng tr×nh minh häa Ch­¬ng tr×nh nµy cã nhiÖm vô t×m kiÕm mét thuËt ng÷ ( t×m kiÕm chÝnh x¸c) trong mét Website nhÊt ®Þnh. Nh÷ng nhiÖm vô cô thÓ cña ch­¬ng tr×nh: Ng­êi dïng nhËp chÝnh x¸c mét thuËt ng÷ vµ mét ®Þa chØ Website cÇn t×m Ch­¬ng tr×nh tr¶ vÒ nh÷ng trang trong Web site vµ sè lÇn xuÊt hiÖn, chóng sÏ ®­îc hiÓn thÞ lªn mµn h×nh Ch­¬ng tr×nh cã thÓ x¾p xÕp gi¶m dÇn sè lÇn xuÊt hiÖn cña thuËt ng÷ trong tõng trang Web §Ó cµi ®Æt mét øng dông cã ®Çy ®ñ c¸c phÇn ®· t×m hiÓu trong b¸o c¸o rÊt phøc t¹p, chóng em chän cµi ®Æt øng dông nµy v× nã thÓ hiÖn c¸c yÕu tè: lËp tr×nh øng dông cã giao diÖn ®å ho¹ trªn Windows, cã giao tiÕp víi Internet, cã sö dông kÜ thuËt ®a luång. Ch­¬ng tr×nh gåm c¸c líp sau: Search Text Engine docfetcher docparser lister Search Engine Search Image Engine Líp lister: giao diÖn víi ng­êi sö dông Líp docparser: ph©n tÝch, tßm kiÕm th«ng tin trang Web Líp docfetcher: lÊy th«ng tin Web pages tõ Internet Ho¹t ®éng cña ch­¬ng tr×nh: Lister nhận thuật ngữ , địa chỉ Website , truyền cho Docparser Docparser truyền địa chỉ Website cho Docfetcher Docfetcher nhận địa chỉ Website , lấy thông tin từ Internet trả về cho Docparser Docparser tìm kiếm , trả về địa chỉ Webpage cho lister, Docparser lấy các link trong trang trýớc rồi lặp lại quá trình tr­íc CÊu tróc d÷ liÖu cña ch­¬ng tr×nh: Giai ®o¹n t×m kiÕm vµ hiÓn thÞ buéc ph¶i tiÕn hµnh song song v× d÷ liÖu tõ mét Website rÊt lín, khã t×m hÕt trong thêi gian ng¾n, ng­êi dïng l¹i muèn nh×n thÊy kÕt qu¶ ngay, nªn 2 viÖc nµy ph¶i tiÕn hµnh ®ång thêi. Ch­¬ng tr×nh sö dông 2 luång, luång 1 chÞu tr¸ch nhiÖm t×m kiÕm, ph©n tÝch th«ng tin tõ Website, ®­a ®Þa chØ trang Web cïng sè lÇn thuËt ng÷ xuÊt hiÖn vµo mét hµng, luång 2 chÞu tr¸ch nhiÖm vµo hµng lÊy ®Þa chØ trang Web cïng s« lÇn xuÊt hiÖn ra hiÓn thÞ. Ch­¬ng tr×nh cã sö dông mét gi¶i thuËt t×m kiÕm nhanh ®Ó t×m kiÕm thuËt ng÷ còng nh­ link trong trang Web. Qu¸ tr×nh duyÖt link trong trang Web sö dông qu¸ tr×nh duyÖt theo chiÒu réng. II. H­íng dÉn sö dông ch­¬ng tr×nh §Ó sö dông ch­¬ng tr×nh nµy, ng­êi dông nhËp thuËt ng÷ cÇn t×m vµo « Input a key word, thuËt ng÷ ph¶i nhËp chÝnh x¸c, kh«ng thõa c¸c kÝ tù c¸ch trèng. §èi víi tiÕng ViÖt , ng­êi dïng cã thÓ sö dông bé gâ VietKey ®Ó gâ tiÕng ViÖt Unicode, hoÆc gâ trùc tiÕp ( ch­¬ng tr×nh ®· tÝch hîp s½n bé gâ Unicode theo d¹ng Telex) vÝ dô: - §Ó nhËp ViÖt Nam sÏ gâ nh­ sau: Vieejt Nam - §Ó nhËp Tæ Quèc sÏ gâ nh­ sau: Toor Quoosc Sau khi nhËp xong thuËt ng÷ , ng­êi dïng nhËp ®Þa chØ Website cÇn t×m: cÇn nhËp ®ñ nh­ sau: [®Þa chØ cô thÓ] [ ….] : phÇn tuú chän VÝ dô: NÕu b¹n nhËp kh«ng ®ñ, nhËp sai hai phÇn trªn ch­¬ng tr×nh kh«ng ch¹y hay ch¹y kh«ng chÝnh x¸c, sau khi nhËp xong, kÝch vµo nót SEARCHING WITH GOOGLE, ch­¬ng tr×nh b¾t ®Çu t×m kiÕm. Thanh StatusBar ë cuèi mµn h×nh hiÖn trang ®ang t×m kiÕm. NÕu t×m thÊy mét trang cã thuËt ng÷, ch­¬ng tr×nh sÏ hiÓn thÞ lªn mµn h×nh cung víi sè lÇn xuÊt hiÖn thuËt ng÷. NÕn muèn xem trang ®ã, ng­êi dïng chØ cÇn kÝch chuét vµo phÇn ®Þa chØ trang. NÕu nh­ ng­êi dïng thÊy kh«ng cÇn t×m n÷a th× kÝch vµo nót “ ENOUGH FOR ME” , ch­¬ng tr×nh sÏ kÕt thóc t×m kiÕm NÕu ng­êi dïng muèn x¾p xÕp c¸c trang theo thø tù tÇn xuÊt xuÊt hiÖn thuËt ng÷ gi¶m dÉn th× kÝch vµo nót “PLEASE ARRANGE” Trong khi ch¹y ch­¬ng tr×nh, nÕu ng­êi sö dông thay ®æi néi dung c¸c hét nhËp, hay kÝch vµo nót SEARCHING WITH GOOGLE th× ch­¬ng tr×nh sÏ kÕt thóc hay t×m l¹i tõ ®Çu III. H­íng dÉn cµi ®Æt ch­¬ng tr×nh ViÖc cµi ®Æt ch­¬ng tr×nh vµ ch¹y ch­¬ng tr×nh kh«ng cã g× phøc t¹p. Mäi ng­êi vµo th­ môc RUN trªn ®Üa CD. Ch­¬ng tr×nh ph¶i ch¹y trªn nÒn .NetFramework. NÕu m¸y tÝnh cña b¹n ®· cã cµi nÒn .NetFramework th× kh«ng ph¶i cµi .NetFramework n÷a vµ bá qua b­íc nµy, nÕu ch­a th× c¸c b¹n vµo th­ môc Microsoft .NetFramework, ch¹y file dotnetfx ®Ó cµi ®Æt nÒn .NetFramework. Sau khi ®· cµi ®Æt xong .NetFramework , b¹n tiÕn hµnh cµi ®Æt ch­¬ng tr×nh ®å ¸n. C¸c b¹n vµo th­ môc: “Bai tap lon huong doi tuong”, ch¹y file cµi ®Æt “CaiDatBaitaplonB5_tin2” hay ch¹y file cµi ®Æt Setup. Ch­¬ng tr×nh cµi ®Æt sÏ h­íng dÉn b¹n thùc hiÖn c¸c b­íc cßn l¹i ®Ó thùc hiÖn cµi ®Æt ch­¬ng tr×nh Sau khi cµi ®Æt ch­¬ng tr×nh, file ch¹y cña ch­¬ng tr×nh lµ file BaitaplonB5_tin2.exe , file nµy sÏ xuÊt hiÖn trªn mµn h×nh Desktop cña m¸y cña ban, trong menu Start -> Program, ë th­ môc mµ b¹n ®· chän khi cµi ®Æt ch­¬ng tr×nh. B¹n ch¹y ch­¬ng tr×nh BaitaplonB5_tin2.exe vµ sö dông ch­¬ng tr×nh. ._.

Các file đính kèm theo tài liệu này:

  • docP0002.doc
Tài liệu liên quan