Monday, 31 May 2004
"Některé věci mají k sobě nepopsatelně blízko" - příkaz switch v jazyce C# a metoda String.IsInterned
Jazyk C# povoluje konstrukci switch, v níž se podmíněná sekce kódu zvolí podle shody proměnné typu string s konstantním řetězcem v sekci case.
switch (myVariable1 + myVariable2)
{
case “sekce1”:
{
//Zpracuj
break;
}
case “sekce 2”:
{
//Zpracuj
break;
}
default:
{
//Nedelej nic
break;
}
}
I když napsání swich výrazu s řetězcem je pro vývojáře jednoduchou záležitostí, zpracování switch výrazu kompilátorem již tak triviální není. Představte si, že porovnání shody řetězců by bylo prováděno znak po znaku. S prodloužením řetězců by docházelo k lineárnímu nárůstu doby potřebné pro porovnání řetězců. Jak asi ze své zkušenosti víte, příkaz case je vždy stejně rychlý bez ohledu na délku řetězců a k žádnému neohrabanému porovnávání řetězců znak po znaku v žádném případě nedochází. Jak je tedy příkaz case kompilátorem zpracován a rozvinut?
Všechny literály (string someString = “Ja jsem literal“) jsou při JIT kompilaci aplikace přidány do speciální hashovací tabulky vytvářené a spravované běhovým prostředím, v níž klíčem je řetězec a hodnotou odkaz (reference, adresa v paměti) na tento řetězec. Podstatné je, že řetězec se stejnou sekvencí znaků se v tabulce vyskytuje nanejvýš jednou. Takže pokud nadeklaruji kromě výše uvedené proměnné someString proměnnou someString2 a inicializuji ji stejným řetězcem jako proměnnou someString ( string someString2 = “Ja jsem literal“)), tak běhové prostředí při JIT kompilaci zjistí, že v hashovací tabulce klíč Ja jsem literal již existuje a proto do proměnné someString2 přiřadí odkaz na objekt umístěný pod tímto klíčem. Proměnné someString a someString2 odkazují poté na stejné místo v paměti, což si lze snadno ověřit voláním metody ReferenceEquals.
Z umístění do hashovací tabulky jsou při JIT kompilaci vyloučeny řetězce, jež jsou konstruovány dynamicky za běhu programu. Takže řetězec v proměnné string someString3 = “Ja jsem literal“ + someString2 přidán nebude. Třída String má ale statickou metodu Intern, jejím účelem je dodatečné vložení řetězce a odkazu na něj do hashovací tabulky. Příkazem String.Intern(someString3) je do hashovací tabulky přidán obsah proměnné someString3.
Když nechceme řetězec do hashovací tabulky přidat, ale chceme se jen dotázat, zda je v hashovací tabulce již obsažen, použijeme další statickou metody String.IsInterned. Metoda IsInterned při nalezení řetězce v hashovací tabulce vrací odkaz na tento řetězec. Když řetězec v hashovací tabulce není, metoda IsInterned vrátí null.
Nyní si už můžete sami odvodit, jak kompilátor efektivně zpracuje příkaz switch s řetězci. Po přechodu na příkaz switch je zjištěn proměnný rozhodovací řetězec, podle jehož hodnoty mají být zvoleny sekce case (switch(myVariable1 +myVariable2) ). Poté je volána metoda String. IsInterned, jíž je předán jako argument rozhodovací řetězec. Když metoda vrátí null, je jisté, že žádná sekce case nevyhovuje rozhodovacímu řetězci, protože všechny řetězce u case sekcí byly přidány do hashovací tabulky při JIT kompilaci. Jestliže metoda vrátí odkaz na řetězec, je testována shoda vráceného odkazu s odkazy řetězců u jednotlivých sekcí case. Když se reference řetězců shodují, je zvolena daná sekce case. Porovnávány jsou jen adresy řetězců v paměti (odkazy, reference), nikdy ne jednotlivé znaky, a proto rychlost provedení příkazu switch není nijak determinována délkou řetězců.
Monday, 31 May 2004 20:39:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework
Thursday, 27 May 2004
O MDA iniciativě, nerozhodných tazích Microsoftu a klukách na pískovišti
Dnes jsem se zúčastnil konference Vývoj celopodnikových aplikací v .NET pořádané Microsoftem a společností LBMS. Na konferenci jsem se přihlásil, protože v pozvánce byla zmínka o MDA (Model Driven Architecture) a já byl zvědavý, jestli na této přednášce bude upřesněn nebo vyjasněn z mého pohledu zdráhavý až macešský vztah Microsoftu k MDA iniciativě.
Protože konference nebyla zaměřena jen na vývojáře, Honza Šeda v úvodu shrnul hlavní výhody .Net platformy a vyzdvihl její přínosy pro segment „Enterprise aplikací". Termín „Enterprise aplikace“ je dnes chameleónskou nádobou, do které si každý s gustem naleje své myšlenky a sny o extra projektu. Já používám pracovní definici, že Enterprise aplikace jsou velmi složitá a drahá řešení, která se významně podílejí na podpoře kritických business procesů firmy a netolerují se u nich chyby ani výpadky:). Jinak řečeno, vývoj a podpora Enterprise aplikace je méně riskantní než kšeftování se zbraněmi, ale zase ne o tolik. :.) Na zbraních ale určitě vyděláte víc.:)
Dle zkušeností z jiných konferencí, kde přednášeli partneří Microsoftu, jsem měl obavu, že i tato konference bude jen zástěrkou pro propagaci produktů společnosti LBMS. Naštěstí tomu tak nebylo. Přednášející z LBMS shrnuli základní rysy a cíle MDA architektury a soustředili se na dominantní koncept PDA – rozvržení různých modelů jednoho systému na hypotetickém grafu, jehož jednou osou je míra izomorfie modelu s přirozenými pojmy z problémové domény a druhou stupeň připravenosti modelu na automatizované generování programového kódu. (Computation Independent Model, Platform Independent Model, Platform Specific Model, o Language Specific Modelu nic nezaznělo). Mapování mezi modely je řízeno exaktními pravidly, i když v přednášce jejich význam nebyl podle mě dostatečně zdůrazněn. MDA tedy nenechává například mapování z analýzy do systémového designu na naší intuici, ale vyžaduje, aby byla pravidla této „hry“ explicitně zachycena, a tím se stala kontrolovatelnými.
Firma LBMS prezentovala svůj produkt Select Component Architect podporující MDA. Hodnotit celou aplikaci zatím nemíním, protože jsme demo Select Component Studia dostali na osahání a reálná zkušenost je vždy věrohodnější než pozorování dobře drezúrovaného přednášejícího, který má instrukce, co z programu předvést, aby dychtivé publikum ohromil, a jaké nedostatky musí naopak taktně zamlčet.
Takže vztah Microsoftu k MDA je dost rozpačitý. Občas pronese silácké prohlášení o svém zklamání z UML a MDA, přičemž u MDA své zklamání spíše anticipuje nebo věští, protože mi uniká, jak se mohu zklamat v něčem, co si svoje místo ve světě softwaru teprve hledá, a jindy zase podpoří své partnery, kteří na MDA a UML vsázejí. Beru to tak, že Microsoft hraje přetahovanou se svým hlavním rivalem IBM a občas si holt umanutě dupne, aby IBM pochopila, že koupí Rational Rose nedeportuje Microsoft na periferii hlavních trendů ve vývoji softwaru. Přejme to oběma firmám, i malí vzteklí kluci na sebe silácky pořvávají, ti tvrdší s gustem přerazí o sebe i pár klacků, ale potom všichni svorně stavějí po celém pískovišti zvelebující bábovičky.
Thursday, 27 May 2004 19:43:00 (Central Europe Standard Time, UTC+01:00)
Analytické drobky
Wednesday, 26 May 2004
Svůdná asynchronní volání v ASP.NET 2.0
ASP.NET 2.0 ulehčí vývojářům práci nativní podporou asynchronních volání. V aktuální verzi 1.1 je prováděno pouze synchronní odesílání formuláře („postback“) Při větším množství „postbacků“, které musíme používat například proto, že plníme některé serverové ovládací prvky podle uživatelem zadaných hodnot v jiných ovládacích prvcích, rychle odhalíme méně příjemné aspekty „postbacků“. Uživatelé, zvláště ti s pomalejším připojením, takové aplikace nepoužívají rádi, protože jim obrazovka neustále nepříjemně problikává nebo musejí nezanedbatelnou dobu čekat na nové zobrazení stránky.
Řešení je mnoho. Ti troufalejší z nás na stránce uloží všechna data bez ohledu na to, že každý uživatel využije jen malý zlomek. Podmíněné plnění prvků je zajištěno JavaScriptem. Nevýhodou je, že uživatelé zbytečně stahují do svého prohlížeče i data, která nikdy nepoužijí. Při větším objemu dat je toto řešení nepřijatelné.
Lepším řešením je například asynchronní volání WWW služby z JavaScriptu nebo využití objektu XmlHttp. Uživatel pracuje a aplikace na pozadí stahuje potřebná data ze serveru.
Do ASP.NET 2.0 bylo přidáno nové API pro asynchronní volání, které vývojáře zbavuje nutnosti znát detailně principy a způsoby zajištění asynchronního volání. Interně ale toto API (alespoň v IE) stále pracuje s komponentou XmlHttp.
Jak nové API vypadá?
Serverový ovládací prvek musí implementovat rozhraní ICallBackEventHandler.
interface ICallBackEventHandler
{
string RaiseCallbackEvent(string eventArgument);
}
Metoda RaiseCallBackEvent přijímá jeden argument typu string s názvem eventArgument, který je zaslán z klientské funkce na stránce v prohlížeči. Může se jednat například o identifikátor kategorie, jejíž výrobky mají být načteny. Metoda RaiseCallBackEvent načte data, ať už z databáze, XML souboru nebo jiného datového zdroje, a ve formě řetězce je vrátí. Návratová hodnota metody je zaslána do prohlížeče, který ji zobrazí nebo jinak zpracuje.
Serverový ovládací prvek si při svém renderování vyžádá od stránky kód v JavaScriptu, který z klienta asynchronně zavolá aplikační logiku na serveru. Do třídy Page byla přidána přetížená metoda GetCallbackEventReference. Zde je jedna z jejích verzí.
GetCallbackEventReference(Control control, string content, string callback, string context);
V argumentu control metoda dostane odkaz na serverový ovládací prvek, pro nějž chceme vygenerovat skript, argument content je názvem metody v JavaScriptu, která poskytne parametr (eventArgument), se kterým pracuje výše popsaná metoda RaiseCallBackEvent. V argumentu callback je název další funkce v JavaScriptu, které má být předán výsledek vrácený metodou RaiseCallBackEvent. Tato fukce se většinou postará o aktualizaci uživatelského rozhraní. V argumentu context je název proměnné v JavaScriptu, kterou používáme pro odlišení různých asynchronních volání. Hodnota proměnné context není nikdy zasílána na server, používají ji jen funkce na klientovi.
Naše funkce v JavaScriptu, jíž je předán výsledek asynchronního volání, musí mít tuto signaturu.
function NazevFunkce (raiseCallbackEventMethodResult, context)
Jak mnou zvolené názvy argumentů napovidaji, v prvnim argumentu je výsledek asynchronního volání a ve druhém obsah proměnné context v okamžiku zahájení asynchronního volání.
V jiné verzi metody GetCallbackEventReference lze zadat také název funkce v JavaScriptu, jež bude zavolána, když v metodě RaiseCallbackEvent dojde k výjimce.
A to je celý trik. V rychlosti zrekapitulujme, jak celý scénář probíhá. Metodou GetCallbackEventReference vygenerovaný klientský kód zavolá na klientovi metodu __doCallBack. Ta získá data z funkce „content“ a odešle je na server, kde běhové prostředí nalezne serverový ovládací prvek, jemuž jsou data určena, zavolá jeho metodu RaiseCallbackEvent a výsledná data zašle zpět na klienta metodě „callback“.
Do třídy HttpBrowserCapabilities byly přidány dvě vlastnosti, abychom si mohli při renderování ovládacího prvku ověřit, zda cílový prohlížeč asynchronní volání podporuje. Vlastnost SupportsCallback nese informaci o přítomnosti nebo absenci podpory asynchronního volání v prohlížeči, ale nesděluje nic o tom, jak jsou případná asynchronní volání realizována. Vlastnost SupportsXmlHttp sděluje, jestli prohlížeč pro asynchronní volání může použít objekt XmlHttp.
Wednesday, 26 May 2004 20:11:00 (Central Europe Standard Time, UTC+01:00)
ASP.NET
Monday, 24 May 2004
Katalog PDA zařízení na MobilManii
Na Mobilmanii přibližně před týdnem spustili testovací verzi katalogu PDA zařízení. K dnešnímu dni v něm najdete kolem 35 zařízení s operačním systémem Windows Mobile nebo Palm OS. Mimo běžného zobrazení všech důležitých parametrů jednoho zařízení si můžete pro detailní srovnání zobrazit vedle sebe až tři zařízení, takže ihned máte například informaci, jak se cenově srovnatelná PDA od sebe liší. Už nemusíme shánět informace o vysněném PDA prosíváním vylučujících se informací na netu nebo se se svými dotazy obracet na většinou ve svém oboru nekompetentní prodavače či infantilně žvatlající "kikiny" na různých infolinkách (bílým vránám v těchto povoláních se omlouvám), ani bastlit v Excelu vlastní srovnávací tabulky.:)
Jestliže si nejste jisti, jaké PDA byste si chtěli koupit, ale máte alespoň matnou představu, k čemu by vám mělo sloužit, a neděsí vás pojmy jako bluetooth nebo WI-FI, tak si po zadání svých nároků na funkce nechte PDA doporučit.
Katalogu se dá vytknout jen to, že v něm nejsou zahrnuty komunikátory, tedy zařízení, která umějí nejen plnit roli kapesního počítače, ale lze z nich i telefonovat. Pod komunikátory jsou řazena hlavně zařízení s operačním systémem Symbian (SE P900), Palm OS (Handspring Treo) a Windows Mobile Phone Edition (MDA II). Pro tyto přístroje je na MobilManii vyhrazen samostatný katalog. Hranice mezi mobilním telefonem, smartphonem, komunikátorem a "čistým" PDA je stále méně patrná, takže schopnost katalogu porovnávat zařízení všech typů by se hodila. I tak jde ale o velmi užitečnou službu MobilManie svým čtenářům.
Monday, 24 May 2004 20:29:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Sunday, 23 May 2004
Bez lásky, naděje a ve vakuu víry - román Písečná kosa Vladimíra Körnera
Vladimír Körner (narozen 1939) je znám hlavně svými filmovými scénáři (Adelhaid, Lékař umírajícího času, Pramen života). Historický román Písečná kosa nezapře autorovo filmové vidění ani to, že historie je pro něj pouhou zástěrkou pro rozehrání dalšího deziluzivního traktátu o selhávajích lidských plánech, neukojených touhách a heroismu zbavených proher. I když Písečná kosa se k dějinám a roli jednotlivce v nich vyjadřuje naléhavým jazykem naplněném obrazností a metaforami, jež ale nejsou patetické ani glorifikující, jak jsme si zvykli u autorů naivní adorujících historické osobnosti (L. Vaňková, J. Loukotková), ale dotvářejí bezútěšnou scenérii, ve které není vítězů. Nanejvýš nevýznamných vítězných odkladů.
V předehře Písečné kosy je v náznacích vylíčena cesta křížové výpravy vedené Fridrichem II do Svaté země. Poutnící prahnoucí po pozemských rozkoších v mysticky pojímaném Jeruzalému-Edenu i v městech po cestě nejsou Boží armádou, ale její nepodařenou lidskou karikaturou. Pohané popírající svými skutky Krista jdou ve jménu své lačnosti osvobodit Jeruzalém od těch, kdo v Krista nevěří. Neúspěch výpravy je zakódován v chování poutníků na cestě, aniž by musel Körner další historická fakta dodávat.
"Oremus - křičeli marně mniši a spínali ruce.
Prosili o trest v samotě a odpovídal jim vzdálený hukot města a přístavu. V průjezdech se smály ženy, v zahradách a keřích rozevíraly svá hedvávná stehna, cítily závrať společného, zmnohonásobeného hříchu sobotní noci. Vyjdou za svítání s čelenkami na hlavách ke svým kostelům. Počkají v prachu, až se otevře brána, a budou se modlit bez stop lítosti nad uniklou nocí. Čím víc hřešily, tím se budou tvářit pyšněji a tím vroucněji budou toužit po spáse."
Již v předehře se setkávám se Sovincem, místem, odkud pochází hlavní hrdina knihy Alwin. Jak pochopíme, Alwina a jeho matku opustil otec, který se nechal zlákat Fridrichovou křížovou výpravou.Mladý Alwin vstoupí do řádu Bratrů svaté panny Marie Jeruzalémské, protože nesnesl, že jeho matka, kterou považoval za symbol čistoty, nevydržela čekat na návrat otce, a našla si milence. Banální událost v životě jeho matky se stane pro Alwina osudovou. Jak vidno, dle Körnera viny nepřecházejí do sedmého pokolení na syny jen z otců.
V řádu Alwin pozná, že za předstíranými ctnostmi vystavovanými na odiv venkovnímu světu je řád, jako každý lidský útvar, prolezlý zlobou, kariérismem, sobectvím a touhou po moci. Řád je jen bezpečnou ulitou pro nectnosti svých členů. Při tažení do Pruska je Alwin svědkem vraždy komtura řádu Rinna. Vrahy nejsou ale pohani, nýbrž skupinka ambiciozních řádových bratří, ve které je i Alwinův domnělý přítel Hanno z Losangenu. Když Hanno Alwina pozná, pokusí se jej zabít. Alwin je zachráněn pohanskou dívkou a ošetřován na hradě panny Amalbergy. Körner se vysmívá všem, kdo neochvějně tvrdí, že dokáží v životě rozeznat přítele od nepřítele. Tuší, že ideologické ani společenské vazby nejsou dostatečným důvodem pro přátelství nebo nepřátelství ani pro lidské nebo bestiální chování.
S Amalbergou se Alwin po svém zotavení spřátelí. Amalberga je pro něj symbolem čistoty. Sama Amalberga osciluje mezi chutí prožít život v lehkomyslném smyslném objetí, i když ví, že její tělo není pro muže přitažlivé, a pocitem, že celý její život patří Bohu, který nesnáší hřích. Událostí s ironií Körnerovi vlastní vyřeší její dilema za ní. Ještě před svým sňatkem s dalším řádovým bratrem Richaredem Clee, ji Richard znásilní. Odevzdání Bohu ani život pod egidou čistoty nás před záměry lidí z masa a krve neochrání.
Alwin se po rozloučení se zlomenou Amalbergou dostane k pohanské ženě Loně. Zde si prožije své nespoutané smyslné léto naplněné milováním bez zábran a bezstarostností. Bez zátěže minulosti a projekcí budoucnosti. Alwin prožije léto, o němž snila, i kterého se obávala Amalberga. Na Alwinovi Körner před čtenářem litujícím Amalbergu, že si nedovolila smyslové radosti a že se sama odsoudila k životu s nenáviděným manželem, rozehraje její druhý potenciální osud.
I hedonická hra smyslů je jen dalším mámením, protože pro Lonu Alwin představuje kratochvilné vyplnění času do doby, než se vrátí její muž. Léto smyslů je vystřídáno zimou, v níž si Alwin po příchodu Lonina muže, zachrání život s pomocí dítěte. Lonina dítěte, které ho po příchodu do vesnice nenávidělo...
Je jedno bezstarostné léto dostatečným smyslem celého života? Nevím, odpovídá po svém zvyku Körner. Jen nám v dalších kapitolách naznačuje (a myslím ze má pravdu), že přežít své smyslné léto je cestou do krajiny zoufalství, vzpomínek a nenaplněných návratů. A neprožít jej vůbec, znamená odsoudit se s grácií-harpyjí k zoufalství ihned.
Alwin se vrátí ke svým bratřím a v samotě se snaží na své zážitky zapomenout a žít podle řádových pravidel. Na řádovém hradě se setká znovu i s Hanem Losangenem a bezděčně se stane příčinou jeho odsouzení za vraždu komtura Rinna. Žádné zadostiučinění ale necítí. Po několika letech Alwin z hradu odchází a poznává, že dlouhý celibát jen vybičoval jeho touhu po ženách a a dlouhé odloučení od světa chuť urvat si z něj co nejvíce. Alwin poznává, že nařízení řádu jsou v rozporu s jeho přirozeností, tužbami i svobodným myšlením. Byť i později zmoudřelý jedinec, který si dovede zachovat dočasně potlačené svobodné myšlení, vždy odhodí kazajku řádu.
Řádem není míněn jen vojensko-církevní útvar, jehož součástí je Alwin, ale libovolná organizace, ať už čistě politická nebo jen agresivní sdružení stejně smýšlejících v nějakém spolku. Körner na tomto místě varuje jakoukoli totalitu, že její nehumánní a násilné nároky na celý soukromý intelektuální i emocionální život jedince nezadržitelně vedou k jejímu pádu, protože se vždy odštěpí skupina lidí – disidentů, kteří své právo na svobodný život a myšlení nesmění s prvním drzým vyvolávačem na trhu ideologií za pestrobarevné materiální cetky.
Jiný autor by se s tímto poselstvím spokojil, Alwina by nechal oženit a vrátil by ho zmoudřelého do Sovince vládnout. U Körnera optimismus na konci kapitoly nevyhnutelně střídá skepse na začátku další kapitoly. I když si Alwin uvědomí, jaké v řádu vládne pokrytectví, neumí nebo nemá sílu žít jinak a jinde. 9. srpna 1241 je Alwin společně se svými "bratry" poslán do bitvy proti Tatarům – apokalyptickému ale hmatatelnému přízraku děsícímu v té době celou Evropu. Bitva je prohrána a mezi padlými je i Alwin. Byl jeho život jen sledem událostí a poznání, jejichž význam Alwin nedokázal nebo nechtěl rozpoznat? Jako příliš mladý a plný ideálů neodpustil matce běžnou a pochopitelnou nevěru a tento morální imperativ se stal hlavním motivem jeho vstupu do řádu, jako starší a zmoudřelý se vrátil do řádu, jenž na svých válečných výpravách dokázal porušit snad všechna přikázání i ideály. I když Körner dává smysl jeho smrti i smrti dalších řádových rytířů, cítíme, ze je spíše přesvědčen, že jednu ztracenou generaci střídá jen předem z(a)tracená generace další. Je jedno, čím se rozměňujeme na drobné. Stejně budeme před Bohem shledání lehkými.
„V tom boji narazili Tataři ponejprv na železné rytíře
; jejich odpor otřásl nájezdníky natolik, že i přes své vítězství nepokračovali v dalších výbojích směrem na západ. Nečekaně se stočili k jihovýchodu, prošli moravskými úvaly a hledali spojení s chánem Batu v Uhřích.
Začínalo nové jaro.
„Zbylí lídé, kteří nebyli pobiti oněmi ranami, neodvrátili se pokáním od skutků svých rukou, nevzdali se klanění démonům a modlám zlatým, stříbrným, měděným, kamenným a dřevěným, které nemohou viděti ani slyšeti, ani choditi. Neodvrátili se pokáním od svých vražd a jedů, ani od svých necudností a krádeží.“ “
Sunday, 23 May 2004 17:18:00 (Central Europe Standard Time, UTC+01:00)
Literární a jiné humanitní úlety
Friday, 21 May 2004
Bezpečná změna verze assembly zveřejněné pro COM
Do konference Emwac VS.NET poslal dotaz pan V. Gazda, jenž se chtěl vyhnout opakované registraci .NET assembly pro COM klienty po změně verze assembly.
Zde je stručný postup vedoucí k eliminaci opakované registrace:
1) Napsal jsem jednoduchou knihovnu s názvem TestLibrary v C#. Rozhraní IType je označeno atributem InterfaceType, kterému je do konstruktoru předána hodnota ComInterfaceType.InterfaceIsDual - rozhraní podporuje brzkou (early) i pozdní (late) vazbu. Rozhraní ITest implementuje třída Test. Z třídy Test je pro Com klienty dostupná pouza metoda Test, protože jsem aplikoval atribut ClassInterface(ClassInterfaceType.None). Možnost None z enumerace ClassInterfaceType registračním nástrojům signalizuje, že z třídy mají být publikovány pouze metody z implementovaných rozhraní (tedy určitě ne zděděné metody).
using
System;
using
System.Runtime.InteropServices;
using
System.Reflection;
namespace
RStein
{
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public
interface ITest
{
void TestMethod();
}
[ClassInterface(ClassInterfaceType.None)]
public
class Test : ITest
{
public Test()
{
}
public
void TestMethod()
{
Console.WriteLine("Hello from COM " + Assembly.GetExecutingAssembly());
}
}
}
2) Vygeneroval jsem silné jméno (strong name), podepsal a zkompiloval verzi 1.0.0.0 assembly.
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyKeyFile(@"..\TestLibrary.snk")]
3) Assembly jsem zaregistroval pro COM spuštěním regasm.exe.
RegAsm.exe TestLibrary.dll /tlb:TestLibrary.tlb
4) Napsal jsem primitivního klienta v C++, který přes COM volá metodu TestMethod z rozhraní ITest. Dle očekávání žádný problém.
#include
"stdafx.h"
#include
<wtypes.h>
#import
"mscorlib.tlb"
#import
"TestLibrary.tlb" no_namespace named_guids
int
_tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
ITest * pTest = NULL;
HRESULT hr = CoCreateInstance(CLSID_Test,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITest,
reinterpret_cast<void**>(&pTest)
);
pTest->TestMethod();
pTest->Release();
CoUninitialize();
}
5) Změnil jsem verzi assembly TestLib.dll na 2.0.0.0, opět jsem kód zkompiloval a umístil do GAC. Verzi 1.0.0.0 jsem z GAC smazal. Po spuštění C++ klienta jsem dostal z metody CoCreateIntance HResult, že nelze nalézt požadovaný soubor.
[assembly: AssemblyVersion("2.0.0.0")]
6) V machine.config jsem instruoval runtime, že nyní mají všichni klienti používat verzi 2.0.0.0 assembly. C++ klient opět typy z assembly TestLib.dll nalezne a žádná opakovaná registrace přes regasm.exe není třeba.
<dependentAssembly>
<assemblyIdentity name="TestLibrary" publicKeyToken="12ba27c531641c01" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
Friday, 21 May 2004 22:14:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework
Wednesday, 19 May 2004
Interval - článek Vývoj sofistikovaných WWW služeb v .Net Frameworku
Na Intervalu mi dnes vyšel článek, který vysvětluje vytváření WWW služeb s použitím nového API pro příjem a zasílání zpráv ve Web Services Enhancements 2.0. Článek je úvodem do světa WSE, v dalších článcích se chci se zaměřit na vysvětlení jednotlivých standardů (ws:addressing, ws:security, DIME atd.). Standardy implementované ve WSE konečně začínají zbavovat WWW služby etikety sice důležité, ale zatím nezralé technologie, které chybí například životně důležité standardy pro bezpečnou komunikaci. WWW služby určené k překonání komunikačních bariér mezi různými operačními systémy i aplikacemi paradoxně nové proprietární berlínské zdi vytvářely, protože každý dodavatel WWW služeb byl nucen autentizaci uživatelů nebo kryptování dat řešit individuálně a jeho volba byla limitována dostupnými prostředky preferovaného vývojového prostředí. V .Net Frameworku jsme si za tímto účelem vyvíjeli rozličné SOAP extenze nebo http moduly.
Microsoft si také chytře vývojem WSE ověřuje životaschopnost, výhody a slabiny nových standardů, aby v Longhornu mohl představit zralou technologii bez (doufejme) zásadních problémů. Jak asi víte, v Longhornu budou WWW služby součástí nového komunikační platformy s kódovým názvem Indigo. Potěšující je, že Indigo by mělo být dostupné i pro starší operační systémy Windows XP a Windows 2003, takže ihned vyvíjet budeme moci i pro zákazníky, kteří jsou při přechodu na nové technologie laxnější.:)
Od vás, čtenářů, bych rád věděl, jestli chcete, abych se v článcích zaměřil jen na praktické použití nových standardů. To znamená hlavně na to, jaké třídy a metody použiji na klientovi a serveru, když chci poslat přílohy nebo co všechno musím udělat/nastavit, abych obsah zprávy zakryptoval atd.. Nebo byste byli raději za hlubší ponor do hlubin standardů, takže bych popisoval i strukturu SOAP zpráv vyměňovaných mezi klientem a serverem a vy byste tak získali lepší vhled do (alespoň pro mě :) ) mimořádně vzrušujícího infrastrukturního pozadí WWW služeb?
Wednesday, 19 May 2004 19:59:00 (Central Europe Standard Time, UTC+01:00)
Web Services
Tuesday, 18 May 2004
Další hrátky s Merge replikací
Tak dnes jsem si lál do příliš brzy zpychlých individuí, protože ve spotu z minulého týdne jsem se chlubil, jak se nám podařilo Merge replikaci zkrotit. Dnes za mnou přišel tester, který dostal za úkol vyzkoušet replikaci ve Virtual PC s Windows XP a souborovým systémem FAT. Uznávám, kombinace Windows XP a FAT zní nesmyslně, ale z mně neznámého důvodu ji na některých stanicích náš zákazník používá, a my jsme si chtěli být jisti, že nebudou při zítřejším releasu žádné problémy.
Tester přišel, že se mu nedaří založit subscription. Vždy nastala tato výjimka :
"System.Runtime.InteropServices.COMException(0x80004005). The subscription to publication <nazev publikace> is invalid.
Překvapilo mě, že k založení "subscription" přes tuto hlášku došlo, protože se zobrazila v sekci Subscriptions v Enterprise manageru. Vyzkoušel jsem založení "subscription" na třech dalších počítačích, virtuálních i hmotných.:) Vše proběhlo bez problémů. Po několika neúspěšných pokusech o založení "subscription" na stroji s XP a FAT, jsem se pokusil zaregistrovat inkriminovaný MS SQL server v mém Enterprise Manageru . Přitom jsem si všiml, že občas se název MSSQL serveru zobrazí, občas ne, registrace selže, ale za 10 sekund již proběhne bez problémů. Začal jsem mít podezření, že jde o síťový problém. Tester se mi až po mém přímém a přiznám už dost nevrle a neomaleně formulovaném dotazu, jaké že to koniny musel provádět s názvem stanice, přiznal, že po instalaci MSSQL změnil název počítače. Vrátit původní název stanici ale nestačilo. Bylo třeba znovu zaregistrovat jméno MSSQL serveru.
Musíte nejdříve zjistit, pod jakým jménem se MSSQL hlásí.
select @@SERVERNAME
Poté odregistrujete server ze seznamu známých serverů.
sp_dropserver <Současný název serveru>
Server znovu zaregistrujete se správným jménem a parametrem 'local'. Pouze jeden server může být registrován jako "local" Od této chvíle bude proměnná @@SERVERNAME vracet nový název.
sp_addserver <Nový název> , 'LOCAL'
Ještě můžete zkontrolovat, že procedura sp_addserver opravdu úspěšně proběhla. Lokální server musí mít ve sloupci Id nulu.
sp_helpserver
Poučení? Merge replikace je opravdu zkrocena, jen nad kreativními testery je třeba nestále práskat varovným bičem. Nemám rád kritickou podmínku úspěchu zvanou lidský faktor.:)
Tuesday, 18 May 2004 19:58:00 (Central Europe Standard Time, UTC+01:00)
(MS)SQL tipy a triky
Sunday, 16 May 2004
Analytikova zkušenost s Ariadninou nití
Svět objektově orientovaného programování je plný různých doporučení, striktních zákazů, nemilosrdně vyžadovaných pravidel i dobře míněných zápisků s petrifikovanými zkušenostmi analytiků-doyenů.
Studiem dokumentace k OOP by mohl nyní jeden člověk strávit celý život a zdá se být kladem, že začínající analytik není odkázán jen na svoji invenci a nemusí stále dokola s Archimédovým výkřikem objevovat dávno známé znalosti, ale zvládne učební křivku na své cestě za téměř dokonalým návrhem (na tomto světě nemůže být nic dokonalé :)) rychleji s využitím přehršle formálních poznatků svých předchůdců. Skoro růžové vyhlídky.:)
Nakonec vždy zjistíme, že mechanická aplikace sebelepších pravidel z nás dobré analytiky neudělá a že ke každému návrhu systému musíme přistupovat s respektem, protože půjde o originál reagující na vždy jiné požadavky zákazníka. Samotný proces návrhu připomíná průchod bludištěm, ve kterém jsou lákavě svůdnou Ariadninou nití zkušenosti jiných i naše vlastní, ale nikdy si nemůžeme být jisti, že postmoderní feministka Ariadna netouží po naší smrti u Minotaura, kterým je formálně dokonalý systém zcela se míjející s reálnými a zákazníkem vyslovenými požadavky.
Po trochu delším úvodu se dostávám k samotnému tématu příspěvku. Jednou z nejdůležitějších a nejvíce akcentovaných charakteristik dobrého návrhu je striktní dodržení principu izolace změn. Většinou se tímo principem míní omezení dopadu změn při rozvoji systému na určitou komponentu nebo třídu bez zásahu do návrhu a kódu ostatních a se změnou nesouvisejících komponent aplikace. Systémy, u nichž každá změna spustí dominový efekt vynucených drobných a těžko dohledatelných úprav, dokáží zákazníkům i dodavatelům připravit těžké noci plné nočních můr o neúspěšném businessu.
Izolaci změn ale nemusíme chápat jen takto omezeně jako prostředek k snadnému rozvoji aplikace. Mnohdy je nutné vyrovnat se ihned v první verzi aplikace s rozdíly při práci s třídami na různé úrovní hierarchie dědičnosti vyplývajícími přímo z aplikace uznávaných objektově orientovaných principů a zamezit šíření zhoubného požáru v podobě duplicitního kontrolního kódu.
Představme si návrh aplikace, ve které existují tři typy produktů. Běžný produkt určený k prodeji, reklamní produkt a konkureční produkt, jímž se míni produkt prodávaný konkurenční firmou. U běžného produktu se evidují tři různé ceny (běžná prodejní cena, cena vzorku a cena, kterou má produkt, je-li předán jako kompenzace obchodníkovi za splněný objem prodeje). U reklamního produktu a konkurenčního produktu se eviduje jen běžná prodejní cena.V diagramu vytvoříme abstraktní třídu ProductBase (ze zde popsaného zadání její nutnost neplyne, ale berte ji prosím jako aplikací vynucený fakt. :) ), která bude obsahovat atribut běžná cena. Potomci ProductBase "Reklamní produkt" a “Konkurenční Produkt" žádný atribut nepřidávají. Dvě další ceny (vzorek, kompenzace) přidá potomek "Běžný produkt". Z hlediska OOP je vše správně, předek ProductBase obsahuje jen společné atributy. Ostatní části systému ale například při zakládání objednávky na produkt budou nuceny při potřebě přistupovat k cenám pro vzorek a rekompenzaci přetypovávat na potomka "Běžný produkt". Nepříjemný způsob, jak do systému zavést závislost na konkrétní třídě a ne na rozhraní a porušit tak další důležitý OOP princip. Ariadna nás poprvé zradila, protože její niť se odvíjí dvěma zcela rovnocennými směry. Pro jaký směr se rozhodnout? U tohoto systému jsem zvolil následující řešení. Produkty měly být řazeny do jednoho či více katalogů, a proto vznikla třída katalogová položka. Položky objednávky si ukazují na položku v katalogu, ne přímo na produkt. Třída katalogová položka má ve svém rozhraní všechny tři ceny. To znamená, že jako jediná v celém systému zná konkrétního potomka ProductBase, se kterým pracuje, a vrací při požadavku na konkrétní cenu buď nulu, pokud u objektu daný atribut neexistuje, nebo získá a vrátí patřičnou cenu delegací na atribut třídy "Běžný produkt". Třída objednávka neobsahuje žádný specifický kód rozlišující mezi typy produktů. Popravdě řečeno, v reálném systému pracují s potomky ještě business pravidla pro objednávky na různé typy produktů, ale ta jsou uložena mimo objekt objednávky ve speciálních "strategiích". Pravidla ověřují platnost a homogenitu položek objednávky. Ale to je opravdu vše - zbytek aplikace pracuje s produkty bez přetypovávání. Milá nerozhodná Ariadno, tentokrát jsem se z tvého ambivalentního vedení vysmekl.
Podobný případ. Když píšete aplikační logiku, která má být společná pro .Net Framework i Compact .Net Framework, brzy zjistíte, že musíte v kódu zohlednit absentující funkcionalitu v Compact .Net Frameworku. Jestliže aplikaci prošpikujete neustálými testy na platformu, nejste vývojáři, ale nejhorší programátorská spodina, pro níž je Minotaurus vysvobozením a panenské Ariadny byste se neměli ani dotknout.:) Jaký je správná postup? Vezměme si jako vzorový příklad řešení nepříjemného poznatku, že v Compact .Net Frameworku překvapivě chybí známá třída ConfigurationSettings.AppSettings pro načtení konfiguračních parametrů. Abyste mohli načíst konfigurační parametry v rámci celé aplikace jednotným způsobem, vytvoříte rozhraní s metodou GetConfigValue. Poté vytvoříte dvě implementace tohoto rozhraní . Jednu pro .Net Framework s využitím třídy ConfigurationSettings.AppSettings a jednu pro Compact .Net Framework, v níž načítání parametrů z XML souboru napíšete sami. Po spuštění aplikace je zjištěna verze operačního systému, a do proměnné, jejímž typem je rozhraní s metodou GetConfigValue, je dosazena platformně závislá implementační třída. Celá aplikace používá jen metodu GetConfigValue a žádné další testy neprovádí. Ač to tak ihned nevypadá, de facto se jedná o návrhový vzor Bridge, v němž konkrétními implementory jsou platformně závislé třídy a odstiňující abstrakcí pro klienty je rozhraní s metodou GetConfigValue. Také zde je dilema - většina OO příruček hlásá, že by v systému neměly vznikat třídy s jednou odpovědností (funktoidy). Ale zde popsané "funktoidy" jsou užitečné a pro vitální funkce sytému nenahraditelné.
Ariadnina niť se u každého kvalitního návrhu systému nenávratně přetrhne a to je většinou spolehlivý příznak, že jsme nalezli vlastní mapu k bludišti a nepotřebujeme zavádějící berličky třetích stran. Příznak toho, že jsme odborně dospěli a neuctíváme již nekriticky OO autority a jejich subjektivní a nutně počtem i typem navrhovaných aplikací podmíněně platné sentence. Včetně našich dosavadních sentencí .:)
Sunday, 16 May 2004 14:10:00 (Central Europe Standard Time, UTC+01:00)
Analytické drobky
Saturday, 15 May 2004
S-Video, SCART - trnitá cesta za černobílým obrazem
Dneska dopoledne jsem se rozhodl, že naplno využiji dřímajícího multimediálního potenciálu :) v přiděleném firemním notebooku IBM ThinkPad R40, který pracovně používám od listopadu, ale zatím jsem nevděčně ignoroval jeho výstup S-Video. Protože jsem v této oblasti úplný laik, nechal jsem se poučit, že S-Video mohu používat i s mojí obstarožní domácí televizí přes SCART konektor. Ráno jsem pln nadšení v místním obchodě s elekronikou u evidentně mým požadavkem konsternovaného prodavače zakoupil S-Video kabel a redukci na SCART. První varovnou indicií měl být fakt, že redukci distribuuuje firma HAMA, s níž mám ty nejhorší zkušenosti. Ale moje chtivost podívat se na nějaký pěkný film byla silnější.
Po návratu domů jsem vytáhl SCART kabel od videa, vložil jeden konec S-Video kabelu do notebooku, druhý konec do SCART redukce a redukci do televize. Po chvilce laborování ve Windows XP se na televizi objevil vytoužený obraz. Skvělý! Ihned po výkřiku radosti přišlo zklamání, protože moje zornice zaregistrovaly, že obraz je pouze černobílý. Sice mým oblíbeným filmům od I. Bergmanna černobílá sluší, ale přeci jen by se výhradní orientace na černobílou produkci podobného ražení mohla podepsat na mém kulturním rozhledu a i tak dost rozháraném duševním zdraví.:)
Po neúspěšných hrátkách s nastavením grafické karty ATI Radeon 7500 a zbytečné instalaci nových ovladačů z IBM centra jsem hledal na Netu vysvětlení té neústupné černobílé anomálie. Výsledek mě příliš nepotěšil - jak to tak vypadá, čeká mě koupě další redukce. Viz http://www.svideo.com/svideoscart.html. Kdyby mi někdo zkušenější mohl doporučit konkrétní typ adaptéru a prodejnu na Netu nebo v Praze, byl bych mu vděčný. Zatím tedy nechám S-Video konektor na notebooku ležet ladem.
Saturday, 15 May 2004 17:26:00 (Central Europe Standard Time, UTC+01:00)
Ostatní
Friday, 14 May 2004
PDA klient pro blogovací systém .Text
Neznáte někdo PDA aplikaci pro psaní spotů pro .TEXT? Já jsem na netu hledal, ale prozatím marně. Rád bych spoty psal přímo z PDA. Jestliže žádný PDA klient neexistuje, tak si jej napíšu, ale bych bych rád, kdyby se našlo více zájemců. Program by byl zdarma, pouze bez zdrojových kódů, což pro ty z vás, kdo mě znají, asi není žádné překvapení:). Moje představa je taková, že by aplikace nejdříve podporovala webovou službu SimpleBlogService pro .TEXT. Nepotřebuji zatím nic jiného než poslat spot do blogu, což tato WWW služba zvládá. V případě zájmu bych napsal i další modul, který by umožnil přístup k blogům podporujícím standardní rozhraní MetaBlog API. Takže moje otázka, milí majitelé PDA, zní. Víte o klientovi, který podporuje blog .TEXT anebo žádný takový není a Vy byste o něj měli zájem? Přeci jen, psát si blog editor jen pro sebe mi přijde jako zbytečný luxus.:)
Teď mě také napadlo, že by bylo příjemné mít klienta pro J2ME v mobilních telefonech nebo mít přístup přes MMS, aby se daly výhledově publikovat zprávy odkudkoli z čehokoli .:)
Friday, 14 May 2004 20:35:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Kniha Network programming for the Microsoft .Net Framework
Kniha Network programming for the Microsoft .Net Framework je úvodem do síťového programování. Slovo úvodem bych zdůraznil, protože žádné rozsáhlé případové studie v ní nenaleznete.
Po obligátním a povrchním úvodu do .Net Frameworku, nás autoři seznámí se “streamy” a pochopitelně se soustředí na třídu NetworkStream. Následuje popis práce s thready a ukázky asynchronního návrhového vzoru (metody Begin*, End*)- i když je problematice věnováno plných 19 stran, nečekejte žádné "best practices", ale spíše upovídaný přepis toho, co je v MSDN. Ukázek asynchronního návrhového vzoru je v celé knize hříšně opulentní množství , takže tato kapitola je jen "lákavou" návnadou.
Dále je v knize vysvětlen význam serializace a probrány jsou XML, binární a SOAP serializace. Když už je serializace probírána do takových detailů, jakými jsou XML atributy, mohla být zmíněna i dynamická redefinice atributů za asistence třídy XmlAttributeOverrides.
Lehký úvod do jmenného prostoru System.Net, jehož smysl mi v kompozici knihy uniká, je vystřídán popisem protokolů IPV4 a IPV6 a metod třídy DNS. Tato kapitola mi připadá z celé knihy nejpovedenější, protože z ní čiší, že její autor své téma podrobně zná, ale přitom dokáže na vyhrazeném prostoru vybrat to podstatné a nezabíhat do zdržujících detailů.
Následující dvě kapitoly tvoří jádro knihy, protože se zabývají klientskými a serverovými sokety a také jejich nadstavbami s jednodušším API (TcpClient, TcpListener). Bohužel tyto kapitoly trpí také největší nevyvážeností ve zpracování tématu. Přístup autorů kolísá od pasivního přejímání informací z MSDN k neustálému zdůrazňování, že pro většinu synchronních metod existují jejich asynchronní doplňky. Když jsem se tuto zajímavou informaci dověděl potřetí a prohlédl si další úmorný Step By Step příklad určený pravděpodobně programátorům po akutní lobotomii provedené brokovnicí, měl jsem chuť připojit se dobře cíleným výstřelem k zástupu šťastných idiotů, abych dokázal kapitoly dočíst. Tam, kde by měla být tématika zpracována velmi prodrobně i s ukázkami, se autoři omezí na shrnující tabulky, jejichž pravděpodobně jediným smyslem je rychlé navýšení počtu popsaných normostran. Moje výtka směřuje hlavně k zcela nedostatečné dokumentaci enumerace SocketOption.
Kromě TCP/IP protokolu jsou zde i ukázky UDP protokolu a implementace takzvaných "Raw" soketů. "Raw" sokety jsou vysvětleny na příkladu ICMP protokolu (což není nic jiného než všem důvěrně známý PING). Slušelo by se zmínit, že na Windows 2000 a XP mohou "Raw" sokety otevřít pouze administrátoři. (ping.exe může spustit každý uživatel, jde asi o jedinou výjimku).
Důležitost tříd WebClient, WebResponse a WebRequest je vyzdvižena v kapitole nazvané "Using the Network". Tato kapitola je povedená, i když zde asi nenaleznete nic překvapivého. Zmíněny jsou cookies, různé způsoby autentizace, certifikáty, SSL.
Z dalších kapitol rychle získáte pocit, že se autoři zavázali dodat dílko o vyšším počtu stran, a proto zařadili témata jako jsou Web Services a .Net Remoting. Sice jsou vždy naťuknuty pokročilé vlastnosti (SOAP extenze, Channel sinks), ale z jejich odfláknutého vysvětlení si začátečník bude brzy zoufat a slabší nátura se k těmto konceptům kvůli neumětelství autorů již nikdy nevrátí. Jako leitmotiv knihy:) se zde objevuje podrobné vysvětlení asynchronního volání WWW služeb.
Autoři se také s těžko pochopitelnou vervou pustí i do vysvětlování Code Acces Security. Jejich snaha se ale omezí na výčet oprávnění a hrubý přehled významu konstitutivních složek CAS, takže kdybych se s CAS setkal poprvé, získám mylný dojem, že CAS je nesmysl bez jakékoli užitné hodnoty. Jsme také poučeni, že bychom měli komunikaci mezi sokety kryptovat, protože svět plný hackerů čeká na naše pakety. Děkuji za osvětu, hned se cítím jako up-to-date vývojář, teď si najdu jen ve slovníku cizích slov význam termínu kryptovat, abych ty hackery svými programy sejmul. :)
Doporučení pro psaní výkonných aplikací jsou shrnuta v mozaice nazvané "Network performance and scalability. Zajímavá je hlavně část týkající se doporučení pro používání "Nagle" algoritmu, ale ani ostatní rady vašim aplikacím neublíží.
Zcela do počtu je kratičká poslední kapitola Advancements in .Net Framework programming, jejíž originální teze by se dala shrnout "Nebojte se, v příští verzi bude zase vše lepší, výkonnější a bezpečnější".
Co říci závěrem? Jestliže se sokety začínáte a jste úplní zelenáči, kniha se Vam bude hodit, i když si z ní odnesete hlavně poznatek, že sokety jsou tady proto, aby bylo na čem demonstrovat dokonalý asynchronní návrhový vzor. :) Jste-li pokročilý vývojář a v knize hledáte neotřelé rady starých zkušených harcovníků, schovejte peněženku, zamáčkněte slzu kanoucí za odpíraným poznáním a vyberte si jiný titul.
Anotace
Název: Network Programming For the Microsoft .Net Framework
Autoři: Jones, A; Ohlund, J; Olson, L;
Nakladatelství: Microsoft Press 2004
Friday, 14 May 2004 20:05:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework | .Net Remoting | ASP.NET | Web Services
Tuesday, 11 May 2004
Zkrocení zlé ženy - "Merge" replikace na MSSQL aneb co v MSDN nenaleznete
"Merge" replikace v MSSQL se používá hlavně tehdy, když má více uživatelů paralelně pořizovat data v odpojeném (offline) režimu. Bonbónkem je u "merge" replikace podpora mobilních klientů (PDA). Uživatelé se připojí, pořízená data odreplikují na server a server jim na oplátku doručí změny v datech provedené ostatními uživateli. Typickými kandidáty na integraci "merge" replikace do designu aplikace jsou systémy pro podporu obchodních zástupců v terénu. Proč se psát s vlastní komponentou pro replikaci, když je zde komponenta již dostatečně otestovaná Microsoftem na nezanedbatelném množství pokusných králíků.:) . Provoz systému s replikacemi ale přesto není triviální, protože se po čase začnou objevovat problémy, jejichž řešení po mobilním telefonu s obchodním zástupcem vyžaduje velkou dávku sebezapření a neustálého sebeujišťování, že si právě teď zasluhujete plat, takže není žádoucí mezi zuby procedit jadrné hodnocení ohledně intelektální potence protějšku, s nímž právě hovoříte.
Proto jsem pro replikace napsal manažera replikaci, jenž je natolik inteligentní, že uživatele většinou ignoruje a jen občas mu dovolí kliknout na nějaké tlačítko :) Na co byste tedy při návrhu vlastního manažera replikací neměli zapomenout?
Ještě upozorňuji, že tato doporučení se týkají hlavně mně důvěrně známé konfigurace, kdy uživatelé přistupují přes VPN k MSSQL serveru s publikací a na svém počítači jsou přihlášení pod lokálním (ne doménovým) účtem. Uživatelé mají na svém počítači databázi MSDE 2000.
1) Ověření dostupnosti lokálního databázového serveru.
2) Kontrola existence lokální databáze, do níž jsou replikována data.
3) Manažer má v rozhraní metody pro založení a zrušení lokální databáze. V konfiguračním souboru je cesta k souborům se skripty pro zrušení a založení databáze.
4) Ověření dostupnosti serveru (počítače) s replikacemi - "Ping".
5) Zjištění, že na serveru běží MSSQL. Prakticky se jedná o ověření, že se lze připojit na port, na němž "poslouchá" MSSQL (standardně se jedná o port 1433).
6) Manažer musí umět založit novou "subscription". "Subscription" je aktivní relace mezi jedním klientem replikace a MSSQL. Na "subscription" je navázána kompletní historie provedených replikací a prohlédnout si ji můžete v Enterprise Manageru. Po uplynutí nastaveného intervalu neaktivity replikace jsou "subscription" na serveru vymazány. Když obchodní zástupce odjede na čtrnáctidenní dovolenou, tak za existenci této metody si můžete dát pořádného panáka Four Roses. Lépe dva:)
7) Komplementární k metodě pro založení "subscription" je pochopitelně metoda pro zrušení staré "subscription".
8) Reinicializace "subscription" bez ztráty existujících lokálních dat. Například při podezření na neúplné schéma databáze u klienta je nutné znovu doručit inicializační snapshot se schématem. Je zbytečné zakládat novou "subscription", postačí reinicializace stávající.
9) Ověření dostupnosti složek, ve kterých je uložen snapshot. Inicializační snapshot musí být před zahájením replikace dostupný. Ověření dostupnosti složek probíhá až po impersonaci uživatele (viz bod 11).
10) Ověření dostupnosti pracovní složky na lokálním počítači, ve které je rozbalován snapshot. Ověření dostupnosti složky probíhá opět až po impersonaci uživatele (viz bod 11).
11) Impersonace speciálního uživatele, který má doménový účet v síti s MSSQL serverem, na němž je vytvořena publikace. Účet má přístup jen k složkám se snapshoty a k lokálnímu pracovnímu adresáři replikace. Celá replikace běží pod tímto speciálním účtem. Impersonaci nemůžete provádět na počítačích, na kterých jsou nainstalovány operační systémy Windows 98 nebo ME.
12) A samozřejmě musíte mít metodu pro spuštění replikace.
A na konec. Měli byste zájem o nějaký podrobný tutorial o vytváření replikací?
Tuesday, 11 May 2004 21:41:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework | (MS)SQL tipy a triky
Monday, 10 May 2004
ftxPBrowser - Pocket PC prohlížeč zobrazující najednou více WWW stránek!
Jestliže používáte na svém Pocket PC PDA verzi Internet Exploreru, asi také stejně jako já nejste nadšeni z toho, že si nemůžete najednou prohlížet více stránek. S každou novou verzí operačního systému Windows Mobile čekám, že se v sekci "New Features" tato funkcionalita objeví. Zatím marně.
Naštěstí již pár let existuje výborný doplněk pro Pocket PC
MultiIE, který Internet Explorer o možnost prohlížení více dokumentu doplní.
Nedávno jsem našel program
ftxPBrowser , jehož stabilní prerelease verze je volně ke stažení. Jedná se o opravdu pěkný kus softwaru.
ftxPBrowser se nainstaluje prostým nakopírováním exe souboru na PDA. Nejedná se o doplněk IE, ale o samostatný program, který ale pravděpodobně pro renderování stránek využívá engine IE, protože stránky v obou programech vypadají totožně. Hlavní funkce ftxPBrowseru:
1) Možnost prohlížení více stránek v samostatných záložkách.
2) U hypertextového odkazu lze zobrazit kontextové menu a v něm zvolit, že odkaz má být otevřen v nové záložce.
3) Ve spodním menu každé záložky je přepínač, kterým se nastavuje, zda chceme odkazy na záložce otevírat v původním nebo novém okně.
4) ftxPBrowser podporuje prohlížení stránek na celé obrazovce (full screen) bez jakýchkoli rušivých ovládacích prvků. Skvělá věc.
5) Zobrazení zdrojového textu stránky. Nádhera:)
ftxPBrowser je pro tyto operační systémy - HandHeld PC 2000, Pocket PC 2002 a Windows Mobile 2003.
Ve verzi 0.1e, kterou používám, mi vadí, že není možné přidávat odkazy do Favorites. Je to ale asi jediný důvod k otevření standardního Internet Exploreru. ftpxBrowser stojí za vyzkoušení a až autor (snad) uvolní ostrou verzi, tak já si ji rád koupím.
Monday, 10 May 2004 15:23:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Sunday, 09 May 2004
Poezie spářená s technickými spoty
Jak jsem avizoval ve svém prvním příspěvku, v blogu by se měly objevit i příspěvky z literatury a příbuzných humanitních oborů. Uznávám, že doména vyvojar.cz vzbuzuje u lačných návštěvníků asi jiná očekávání a aktivuje spíše jejich technicky orientované kognitivní touhy, ale snad se nikdo z Vás nezačne barbarsky kuckat hned, jak uvidí první strofy nějaké básně. Ani
pan domácí
zatím neprotestoval :) a nejen neosobními a většinou fádními novinkami v IT živ je člověk. Přemýšlel jsem, čím bych měl literární sekci otevřít. Protože je weblog subjektivní žánr, ve kterém by ale rozšafný autor neměl od pohodlné klávesnice dle svého naturelu pouze kritizovat nebo chválit tvorbu ostatních, rozhodl jsem se premiérově dát v plen něco ze svých pokusů v oblasti poezie, abych zřetelně subjektivní charakter spotu umocnil. Usnadněno jsem to měl tím, že na „lyrický věk“, jak trefně období, kdy je nutkání psát poezii nejsilnější, nazval Milan Kundera, jsem již asi definitivně zanevřel. Takže Vaše interpretace, názory, nadávky, averze jsou vítány, a protože nevládnu mocí zneuznaného dandyho, šílence a císaře Nera, nemusíte se ani obávat následků svých výlevů :).
Prosívám
Prosívám nerozumění Tebou darované
Mě do žil zvolna ztrácejících tep dechu
Aby se tok horkosti v zpěněné šílenosti sevřené
Dechem odmítání a krásy padlého prachu
Otevřel –
Les úzkosti vystavěný ze snů a praskotů temnoty
Rozevlátá moc svou dlaň obtiskává do hmoty
Z níž jak z már nečekání a odevzdání
Naprasklé zlaté hrany – vlání, vlání –
A otvírání –
Klečívám v modlitbách a pokora plenění
Příkazem shora i zdola – obemykající vlasy
V nichž mé oči zjitřené v tvém pásu obklíčení
Škvírami zúženými na smuteční hlasy
Se otevřou –
Prostor srůstání přechodných stavů
I ztišení neviditelných v trhlinách stenů
Vyluzujících rozedrávající morkodření
Pro obyvatele nevinnosti i procitání
A otvírání
Vzývávám vyzývavě jazykem zapálení
Průzračné i znovuhynoucí tvořivosti
Jíž v rukou mnou již nevlastněných zachvívá se
Třepotání křídel a jíž se brána malosti naší
Otvírá –
Vydýchání krve – mé či tvé – snad ničí
Kde ještě život ve zlou apoteózu smrti
Vchází a srůstá s mlhou – mlčí
I pak – i pak – i pak sám rozkrývati
Na těle tvém otevřeném
A vlahém mým dechem
O slitování rouhat budu se
Když les úzkosti odkazovaný
Od věků a klamný
Vláním, Vláním
A všepohlcujícím
Otvíráním
Temným
Stráním
Jež jsem zvolil a přijal
Tebe uzavřel
Hříčka o jaru
Je jaro a mně se zdá
že vichr na zem dopadá
Neodpouští, co v nás umírá –
Je jaro – z výšky si nás obzírá
Za oknem zprůsvitnělým raší stromy
Do nebe hrozí – na něm rány
Erbovní symptomy dlouhé nemoci svírající svět
Hle hlupáčku! Vždyť tamhle raší květ!
A někde další, další
Ach moji lidé plaší
Co na jaře se to v nás splaší
Že radujem se a ke křiku jsme hluší
Však vichr na zem dopadá
A nevěstu znásilňuje – ta vždy uvadá
Kam zmizí ženská paráda
Když nás pak zimě prodává
Sunday, 09 May 2004 13:31:00 (Central Europe Standard Time, UTC+01:00)
Literární a jiné humanitní úlety
Friday, 07 May 2004
Uložení důležitého stavu serverových ovládacích prvků v ASP.NET 2.0
ASP.NET 1.0 přineslo pro vývojáře WWW aplikací několik zásadních novinek. Jednou z nejlepších je simulace stavového chovaní prvků pomocí ViewState. U každého serverového ovládací prvku je před vyrenderováním stránky volána metoda SaveViewState, ve které prvek uloží všechny informace potřebné k obnovení stavu. Kompletní stavová informace stránky je poté uložena ve skrytém (hidden) poli na klientovi. Po odeslání formuláře (PostBacku) je volána metoda LoadViewState všech prvků a je jí předán stav uložený metodou SaveViewState. Metoda LoadViewState obnoví stav prvku a poskytne tak vývojáři i uživateli skoro dokonalou iluzi stavového chování známého hlavně z těžkých klientů. Slovo "skoro" jsem použil záměrně, protože je často nutné z výkonnostních důvodů ukládání ViewState zakázat, aby na klienta a pak zpět na server nebyly přenášeny velké objemy dat. Můžeme sice přepsat metody LoadViewStateFromPersistenceMedium a SaveViewStateToPersistenceMedium třídy Page a ukládat ViewState například do databáze na serveru, ale v praxi se tento postup příliš neujal. Ukládání ViewState můžeme zakázat všem ovládacím prvkům na stránce, častěji ale ukládání ViewState zakážeme pouze u vybraných prvků, jež by do ViewState přidaly nejobjemnější položky. Po zakázání ViewState se ale většinou setkáme s problémy, jejichž řešení zabere nezanedbatelné množství času. Například DropDownList si po zákazu ViewState "nepamatuje" vybranou položku (SelectedIndex), takže uložení a nastavení indexu vybrané položky musíme při každém odeslání formuláře řešit sami. ViewState v .Net Frameworku 1.0 vyznává zásadu "všechno nebo nic", ale my bychom často potřebovali ukládat důležitý stav bez ohledu na nastavení ViewState vývojářem. Nemusíme ukládat do ViewState zrovna celý číselník, ale index vybrané položky přenosovou linku nijak nezatíží a programování extrémně zjednoduší.
ASP.NET 2.0 proto přichází s novinkou - kromě ViewState lze ukládat i takzvaný ControlState. O ukládání do ControlState rozhoduje výhradně vývojář serverového ovládacího prvku, jehož odpovědností je, aby do ControlState byla uložena jen data důležitá pro základní činnost prvku. Určitě ale do ControlState nesmí být ukládány DataSety, kolekce ani jiné objemné objekty. Dále platí, že stavová data jsou uložena do ControlState nebo do ViewState, nikdy ne do obou stavových úložišť! Výsledný ControlState celé stránky je ukládán na klientovi ve skrytém poli s nepřekvapivým názvem __CONTROLSTATE.
Ukládání do ControlState se příliš neliší od ukládání do ViewState. Hlavním rozdílem je to, že serverový ovládací prvek si musí vynutit ukládání a načítání ControlState voláním metody RegisterRequiresControlState třídy Page.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
Ve veřejné metodě SaveControlState před vyrenderováním stránky uložíme důležitý stav prvku a vrátíme jej. Návratovým typem metody je typ object, takže můžeme vrátit jakýkoli serializovatelný(!) objekt. V ukázkovém kódu je ukládán ControlState bázové třídy a poté hodnota vlastnosti SelectedIndex.
public override object SaveControlState()
{
object baseState = base.SaveControlState();
object[] savedSate = { baseState, this.SelectedIndex};
return savedState;
}
Metoda LoadControlState po odeslání formuláře obnoví dříve uložený ControlState. Z argumentu state je po přetypování obnoven nejdříve ControlState bázové třídy a poté hodnota vlastnosti SelectedIndex.
public override void LoadControlState(object state)
{
object[] savedState =(object[]) state;
base.LoadControlState(savedState[0]);
this.SelectedIndex = (int) savedState[1] ;
}
Friday, 07 May 2004 15:47:00 (Central Europe Standard Time, UTC+01:00)
ASP.NET
Thursday, 06 May 2004
Windows forms combobox jen pro čtení
Nedávno jsem potřeboval zakázat v detailu uživateli výběr z comboboxu, ale zjistil jsem, že první nabízející se cesta přes vlastnost Enabled není vhodná. Když nastavíte vlastnost Enabled na false, tak sice uživatel žádnou položku nevybere, ale combobox působí na formuláři jako grafický "umrlec", protože dříve vybraná položka je "zašeděná". Potřeboval jsem vlastnost, která by ponechala vizuální vzhled comboboxu beze změny, ale nedovolila provést nový výběr.
Žádnou takovou vlastnost jsem nenašel, a proto jsem vytvořil potomka comboboxu, kterému jsem přidal vlastnost DisableDropDown. Když je vlastnost DisableDropDown true, tak combobox v přepsané metodě OnWndProc ignoruje zprávy o stisku tlačítka myši (WM_LBUTTONDOWN a WM_LBUTTONDBLCLK) a zprávy z klávesnice (WM_KEYDOWN, WM_KEYUP) . V další přepsané metodě OnKeyPress combobox zamezí zadání nové položky do textového pole nastavením vlastnosti Handled argumentu e na true. To je celý trik, snad se bude odvozený combobox hodit i Vám.
using
System;
using
System.Windows.Forms;
namespace
RStein.UI
{
///
<summary>
///
Combobox, u nějž je možné zakázat rozbalení seznamu položek a editaci textového pole
///
</summary>
public
class
ComboBoxEx : ComboBox
{
private
const
int
WM_KEYDOWN = 0x0100;
private
const
int
WM_KEYUP = 0x0101;
private
const
int
WM_LBUTTONDOWN = 0x0201;
private
const
int
WM_LBUTTONDBLCLK = 0x0203;
#region
private fields
private
bool
m_disableDropDown =
false
;
#endregion
private fields
///
<summary>
///
Konstruktor
///
</summary>
public
ComboBoxEx()
{
m_disableDropDown =
false
;
}
#region
public properties
///
<summary>
///
Zakázat zobrazení položek?
///
</summary>
public
bool
DisableDropDown
{
get
{
return
m_disableDropDown;
}
set
{
m_disableDropDown =
value
;
}
}
#endregion
public properties
#region
protected methods
protected
override
void
OnKeyPress(KeyPressEventArgs e)
{
if
(!DisableDropDown)
base
.OnKeyPress(e);
else
e.Handled = true;
}
protected
override
void WndProc(ref Message m)
{
if (!DisableDropDown)
base.WndProc (ref m);
else
if ((m.Msg != WM_KEYDOWN) &&
(m.Msg != WM_LBUTTONDOWN ) &&
(m.Msg != WM_LBUTTONDBLCLK) &&
(m.Msg != WM_KEYUP))
base.WndProc (ref m);
}
#endregion
protected methods
}
}
Thursday, 06 May 2004 21:15:00 (Central Europe Standard Time, UTC+01:00)
Windows Forms
DIGI TRADE součástí skupiny PC-WARE
Firma
DIGI TRADE, ve kterém jsem zaměstnán, se včera stala součástí mezinárodní skupiny
PC-WARE. Další krok za námi, vypadá to, že se můžeme těšit na rozsáhlé a doufám i komplikované mezinárodní projekty. Nové zkušenosti, příležitosti, žádný stereotyp, přesně to, co mám rád. U sklenky šampaňského také doufám, že se nám vyhnou mezinárodní průšvihy, ty internacionalizovat nemusíme.:)
Thursday, 06 May 2004 13:44:00 (Central Europe Standard Time, UTC+01:00)
Ostatní
Wednesday, 05 May 2004
Moderní architektura očima Microsoftu aneb rozpaky nad vizemi
Na konferenci, jejíž název je v titulku spotu, jsem strávil dnešní den. Microsoft na ní po úvodní přednášce prezentoval hlavně BizTalk, takže jsem ji bral jako pokračování praktického semináře z minulého týdne. Úvodní přednášku měl Michael Juřek a vysvětloval v ní, jak Microsoft reaguje na požadavky firem integrovat existující aplikace bez velkých nákladů, ale přitom způsobem, který mezi aplikacemi nevytváří více a více se svírající osudové kruhy.
Určitě osudové kruhy znáte, aplikace A využívá databázi aplikace B, ta si sáhne do databáze aplikace C pro autorizované uživatele a na oplátku v aplikaci A vyřídí faktury. Aplikace D si také ráda sosne z jiných zdrojů a máme zde solidní mikromodel chaosu. Aplikace jsou těsně provázány a přitom neexistuje jediný závazný model jejich komunikace. Ano, nebojte se, padlo i magické zaklínadlo dnešních dnů, SOA, ale kupodivu v sále hysterie nepropukla, potože Michal Juřek naštěstí nepronáší pojem SOA tak vznešeně, jak by si fanoušci buzzwords asi přáli.:) Pokud tento spot čtou šťastlivci, kteří o SOA (Service oriented architecture) neslyšeli, tak vězte, že Microsoft se přklonil k této definici služby - "Služba je autonomní část software, která implementuje logiku v podobě kódu, spravuje svůj stav, komunikuje prostřednictvím zpráv, je řízena politikou a je dostupná po síti". Když se nad touto definicí zamyslíte, tak zjistíte, že ji asi můžete napasovat na jakoukoli komponentu. Dosti žertování, bez ohledu na zbytečný humbuk kolem SOA je opravdu zřejmé, že se již dnes stále více prosazují integrace na bázi WWW služeb, u nichž nás nezajímá implementace, ale pouze struktura platformně a infrastrukturně nezávislých zpráv, které jim mohu zaslat a které mi pošlou jako odpověď. Jinými slovy, zajímá mě jen závazný protokol pro výměnu zpráv (kontrakt) mezi mnou a službou, vše ostatní je zcela irelevantní. Cílem integrací je také zrušení těsných závislostí mezi aplikacemi nasazením inteligentního prostředníka, který jejich spolupráci koordinuje. Na platformě Microsoftu je tímto integrátorem (brokerem) BizTalk.
Mimochodem - víte, kdy začnu respektovat fanoušky SOA? Až dokážou napsat WSDL WWW služby ke komponentě z hlavy - tomu říkám znalost technologie a respekt k ní:)
Nejen tato, ale i další přednášky Michala Juřka se mi líbily. Horší to bylo s částmi, které měl na starosti Miloš Sobotka. Jeho prezentace byly velmi nekonvenční, takže jsem brzy nabyl dojmu, že ho Microsoft předtím omylem vyslal na kurz asertivity místo potřebného kurzu prezentačních dovedností . Jeho ústní projev byl plný pomocných frází, zaumných přeřeknutí a rozverných anglicismů, přednáška neměla žádnou logickou kostru, prezentace dema vetšinou nedopadla podle jeho představ, ale všechnny tyto nedostatky zvládl s labilním smíchem asertivně bagatelizovat a vystavit jako přednost.:) Nebyly to informačně hodnotné přednášky, ale docela jsem se pobavil.:)
Na konci konference byly zodpovězeny naše dotazy a dostalo se i na vztah Microsotu k UML. UML 2.0 má silnou podporu pro modelování dynamického chování, a proto asi nejen mě zajímalo, jestli se v BizTalku i dalších produktech návrh procesů v UML objeví. Zvláště poté, co prosákly zprávy, že Microsoft k UML dobrý vztah nemá. Bohužel, nešlo o žádné pomluvy, Microsoft si s UML opravdu nerozumí. Já ale zase asi nerozumím Microsoftu. Jak může na konferenci o moderní architektuře bezelstně přiznat, že mu jeden z nejdůležitějších nástrojů analytika, designéra a architekta nesedí? Proč se chce vydělit z MDA iniciativy?
Oficiálně byly sděleny zatím tyto důvody pro vlažný vztah k UML.
1) UML je pro běžného vývojáře příliš komplikované. Microsoft se vždy údajně orientoval na "masového" vývojáře, který nemá žádné komplikované věci rád, a UML by tuto orientaci popřelo. Opravdu je pro Vás, kdo tento spot čtete, UML složité? A hlavně, v čem je pro Vás složité? Mně přijde jako jednoduché, čisté a elegantní. Znamená to, že JAVA vývojáří UML zvládnou, ale C# vývojář má potíže? Já myslím, že ne a že jde o pouhý alibismus kvůli bodu 2. Jsem také skeptický v tom, že Microsoft by přišel s něčím stejně výkonným jako je UML a přitom by šlo o jednodušší jazyk. Nechci hračky vhodné na splácání projektu o 10 třídách a odškrtnutí kolonky "Analýza hotova" v projektovém plánu.
2) Firma Rational Rose byla koupena IBM a IBM je konkurence, takže podpora UML by byla pro Microsoft schizofrenní. Tenhle argument už vypadá věrohodněji, protože Microsoft zcela jistě nebude podporovat konkurenci. Ale přesto, UML nepatří IBM, UML je průmyslový standard. Nevylévejte s vaničkou dítě, které má skvělé geny. A ty geny nejsou po adoptivních rodičích-vlastnících. Zásadovost je správná a konkurenci je třeba potřít, ale UML s tímhle bojem nemá nic společného. Vývojáři mohou použitím UML jen získat, ale UML je nesvede k laškování s IBM technologiemi. Věřte mi, jsem živý důkaz:)
Wednesday, 05 May 2004 20:14:00 (Central Europe Standard Time, UTC+01:00)
Analytické drobky
Tuesday, 04 May 2004
Oskar spustil víkendová volání "zdarma"
Náš benjamínek mezi mobilními operátory nabízí volání o víkendu zdarma všem novým zákazníkům, kteří si aktivují jeden z tarifů nové generace - Řekni mi (volání zdarma na 3 měsíce), Povídej (6 měsíců) a Nezavěšuj (12 měsíců). Zní to hezky, ale názvy PR zpráv většinou realitu přikrášlují, tak se podívejme, na kolik si u Oskara ocenili hovory "zdarma" pro stávající zákazníky.
Stávající zákazníci tedy nepřijdou zkrátka, ale nedostanou ani slevu zadarmo, a za neomezené víkendové hovory zaplatí měsíční poplatek 178,50. Jde sice o zajímavou nabídku, protože na českém telekomunikačním trhu jsou bezlimitní paušálně zpoplatněné hovory raritou, ale o žádný zázrak se nejedná. Oskar se snaží podobně jako dříve T-Mobile zatraktivnit volání v době, kdy je kapacita sítě málo využívána. Pochybuji ale, že se najde dostatek nadšených šílenců, kteří zaplatí 178 Kč, aby si mohli po telefonu poklábosit se svými známými v době, kdy mají volno a mohou je navštívit osobně. Napadají mě pouze odloučení zamilovaní, ti musí při uvedení tohoto tarifu jásat. :) Jako bonus by jim ale mohl Oskar k aktivaci tarifu přidávat handsfree sadu. Kdo již absolvoval delší hovor přes mobil, tak určitě ví proč.
Možná je ale Oskar fikanější a počítá s tím, že si tolik zákazníků tarif neaktivuje, ale přesto se bude moci prezentovat jako operátor, který má kapacitně tak naddimenzovanou síť, že si může dovolit nabízet neomezené hovory. Oskar má stale pověst laciného operátora, jehož síť ale za moc nestojí, a touto akcí by mohl získat cennou reputaci i v oblasti technické vyspělosti sítě, kterou marketingové oddělení jistě zúročí. Oskar se nám sice nyní v reklamách prezentuje jako adolescent, kterému nechybí sebevědomí a který ví, že všechny problémy zdolá svým roztomile naivním a neodolatelným sloganem"stačí říct", ale vědom si fyzických limitů GSM sítě nastavil podmínky provozování této služby přeci jen střízlivěji.
Ze závažných technických nebo provozních důvodů může Oskar přerušit nebo zastavit poskytování tohoto balíčku dle všeobecných podmínek.
Tuesday, 04 May 2004 16:43:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Monday, 03 May 2004
Znáte třídy ServicePoint a ServicePointManager? Měli byste...
Při používání více threadů například pro získání obsahu WWW stránek ze stejného URI nebo při asynchronním a současně prováděném volání více metod jedné WWW služby se můžete setkat s podivnými výjimkami nebo ještě podivnějšími prodlevami mezi jednotlivými voláními.
Za rovnoměrné využití síťových zdrojů je odpovědná třída ServicePointManager. Ta obhospodařuje kolekci objektů ServicePoint, které jsou vytvářeny při prvním požadavku na dané URI. Třída ServicePointManager má několik zajímavých vlastností a metod.
Vlastnost DefaultConnectionLimit - hodnota vlastnosti určuje, kolik konkurenčních připojení může ve stejném okamžiku přistupovat ke stejnému URI. V .Net Frameworku 1.1 jsou ve výchozím nastavení povolena dvě konkurenční připojení na stejné URI. Jestliže například z nějakého důvodu potřebujete asynchronně a "najednou" volat více metod WWW služby, měli byste ConnectionLimit zvýšit.
Vlastnost MaxServicePointIdleTime - tato vlastnost říká, jak dlouho musí být dané URI neaktivní, aby se stalo kořistí Garbage Collectoru. Neaktivní znamená, že s daným URI nebylo po zadanou dobu vytvořeno žádné spojení. Výchozí hodnotou je 900.000 milisekund (15 minut)
Vlastnost MaxServicePoints - tato vlastnost říká, kolik instancí ServicePoint může být vytvořeno. Jinými slovy, tato vlastnost omezuje počet URI, na které se lze v jednom okamžiku připojit. Ve výchozím nastavení žádný limit neexistuje (vlastnost obsahuje hodnotu 0).
Metoda FindServicePoint - přetížená metoda FindServicePoint vrátí objekt ServicePoint pro zadané URI. Když ServicePoint pro URI ještě neexistuje, tak metoda vytvoří a vrátí nový objekt ServicePoint, jinak je vrácen existující ServicePoint.
U třídy ServicePoint můžeme upravit vlastnosti, jež jsou po vytvoření objektu inicializovány výchozími hodnotami převzatými z třídy ServicePointManager.
ConnectionLimit - má stejný význam jako vlastnost DefaultConnectionLimit u ServicePointManageru.
MaxIdleTime = má stejný význam jako vlastnost DefaultConnectionLimit u ServicePointManageru.
Tak a teď jednoduchý demonstrační kód konzolové aplikace. Nejdříve kód, který změní DefaultConnectionLimit tak, aby odpovídal počtu požadavků (WebRequest). Vše proběhne relativně rychle a dle očekávání.
using System;
using System.Net;
using System.Threading;
namespace RStein.ServicePointManagerTester
{
class ServicePointManagerTest
{
static void Main(string[] args)
{
Console.WriteLine(ServicePointManager.DefaultConnectionLimit);
ServicePointManager.DefaultConnectionLimit = 4;
WebRequest reg = WebRequest.Create("http://wwww.atlas.cz");
WebRequest reg2 = WebRequest.Create("http://wwww.atlas.cz");
WebRequest reg3 = WebRequest.Create("http://wwww.atlas.cz");
WebRequest reg4 = WebRequest.Create("http://wwww.atlas.cz");
WaitHandle handle0 = reg.BeginGetResponse(new AsyncCallback(test), reg).AsyncWaitHandle;
WaitHandle handle1 = reg2.BeginGetResponse(new AsyncCallback(test), reg2).AsyncWaitHandle;
WaitHandle handle2 =reg3.BeginGetResponse(new AsyncCallback(test), reg3).AsyncWaitHandle;
WaitHandle handle3 =reg4.BeginGetResponse(new AsyncCallback(test), reg4).AsyncWaitHandle;
WaitHandle.WaitAll(new WaitHandle[] {handle0, handle1, handle2, handle3});
Console.WriteLine("vse");
Console.Read();
}
private static void test(IAsyncResult ar)
{
Console.WriteLine("Konec requestu");
try
{
WebRequest reg = (WebRequest)ar.AsyncState;
WebResponse response = reg.EndGetResponse(ar);
response.GetResponseStream().Close();
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
Nyní změňte DefaultConnectionLimit na 1. Jak můžete pozorovat, vyřízení všech požadavků je citelně pomalejší (alespoň u mě na GPRS), protože jsou vyřizovány jeden po druhém. K URI "www.atlas.cz" může vždy přistoupit pouze jedno připojení. Mimochodem, víte proč se v MSDN neustále zdůrazňuje, že je třeba co nejdříve uzavřít všechny použité streamy? Jestliže ne, upravte řádku response.GetResponseStream() Close() ; na response.GetResponseStream(); a spusťte znovu aplikaci.
Monday, 03 May 2004 21:21:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework
Sunday, 02 May 2004
T-Mobile ponechá tarif GPRS Unlimited za 699 Kč (bez DPH)
Jestliže jste to ještě nezaregistrovali, T-Mobile ve své tiskové zprávě oznámil, že ponechá cenu 699 Kč za neomezený přístup k Internetu přes GPRS. Předchozí cenově zvýhodněný tarif GPRS Business Unlimited jsem si aktivoval ihned po jeho uvedení v listopadu a i když nejde o žádné zázračně rychlé připojení, na stahování pošty, připojení do VPN, prohlížení webu a psaní příspěvků do weblogu bohatě stačí. Vím ale, že vděčnost za tento tarif, i podobný a dříve uvedený tarif Data Nonstop od Eurotelu, má svůj zdroj spíše v sebevražedné cenové politice žáby na prameni s internetovým připojením - Českým Telecomem.
V červnu se cena tarifu GPRS Business Unlimited měla vyšplhat na 999 Kč, ale T-Mobile se rozhodl jinak. Zdá se, že jeho rozhodnutí není jen nahodillým vstřícným gestem směrem k zákazníkům, ale spíše promyšlenou součástí dříve oznámeného ambiciozního plánu přestat být tím "stále druhým" na českém trhu. Jedničkou v počtu zákazníků i tržbách je stále Eurotel, který profituje z dřívějšího startu GSM sítě, z věrností ochotně platících business zákazníků a ze změny image u lidí v minulém roce, která byla způsobena hlavně uvedením zmiňovaného tarifu Data Nonstop. Nyní ale T-Mobile zavětřil, protože odvolání Terence Valeskiho z funkce jednatele společnosti a jeho očekáváný odchod z pozice generálního ředitele Eurotelu znamená, že Český Telecom začíná ve své dceřinné firmě úřadovat dle svého gusta. Dle zkušeností s předchozím jednáním Českého Telecomu se dá očekávat, že jeho vliv bude mít za následek pouze oslabení současné skvělé tržní pozice Eurotelu. Pro Český Telecom je důležité prosadit ADSL (ISDN snad už ani on tlačit nebude) a konkurenci v podobě CDMA nebo i GPRS, byť z domovské stáje, asi příliš podporovat nebude. Jediné, co by snad dokázalo přivést Český Telecom k racionálnímu jednání, by byl právě rychlý nárůst tržního podílu TMO na úkor ET. Takže další kolo souboje o post nejúspěšnějšího operátora začíná a Eurotel podle mého soudu poprvé není favoritem.
Sunday, 02 May 2004 19:35:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Dva nejčastější dotazy k .NET Remotingu
V diskuzních fórech se objevuje mnoho dotazů k .NET Remotingu, ale následující dva jsou evergreenem. Těm z Vás, kdo záludnosti .Net Remotingu ještě neodhalili sami, nabízím řešení a doufám, že dotazů ve fórech ubude.:)
V .Net Frameworku 1.1 dojde při pokusu o komunikaci se vzdáleným objektem k výjimce SecurityException nebo SerializationException. V .Net Frameworku 1.0 aplikace funguje bez problémů.
.Net Framework 1.1 z bezpečnostních důvodů nepovoluje ve výchozí konfiguraci deserializaci všech typů, takže k výjimce dojde například při předání potomka třídy MarshalByRefObject z klienta na server nebo při registraci delegáta k události. Řešením je nastavit u objektu formatter, který provádí (de)serializaci, že povolujeme deserializaci všech typů. Úroveň deserializace vyjadřuje enumerace TypeFilterLevel a chování shodného s verzí 1.0 dosáhneme použitím hodnoty Full. Hodnotu Full přiřadíme objektu formatter (přesněji poskytovateli objektu formatter) v konfiguračním souboru nebo přímo v kódu. Nastavení úrovně full musí být provedeno na serveru a když používáte zpětná volání (callback) nebo události, tak musíte úroveň Full nastavit i na klientovi. Nezapomeňte, že byste měli zprávy mezi klientem a serverem přenášet přes https nebo je alespoň kryptovat.
Nastavení v konfiguračním souboru
Server
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel ref="http" port="7777">
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
Klient
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel ref="http" port="0">
<clientProviders>
<formatter ref="binary" />
</clientProviders>
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
Nastavení v kódu
BinaryServerFormatterSinkProvider binProvider = new BinaryFormatterSinkProvider();
binProvider.TypeFilterLevel = TypeFilterLevel.Full;
SoapServerFormatterSinkProvider soapProvider = new SoapServerFormatterSinkProvider();
soapProvider.TypeFilterLevel = TypeFilterLevel.Full;
Za další otázkou se skrývá záludnější problém. Při použití http kanálu, binárního formatteru (formátovač mi nějak do pera nejde) a hostování vzdáleného objektu v IIS dostanete na klientovi občas následující výjimku.
An unhandled exception of type 'System.Runtime.Serialization. SerializationException' occurred in mscorlib.dll
Additional information: BinaryFormatter Version incompatibility. Expected Version 1.0. Received Version <nesmyslné číslo>
Matoucí je hlavně nesmyslné číslo na konci, které zcela evidentně nepředstavuje žádnou známou verzi formatteru a tedy nelze jednoduše nalézt pravou příčinu nepovedené deserializace. Vysvětlení je prosté - došlo k chybě na úrovni IIS a klientovi se vrátí chybové http hlášení (například HTTP/1.1 500 Internal server error), protože WWW server/vzdálený objekt není z nějakého důvodu dostupný. Bohužel formatter se snaží nalézt v této zprávě hlavičku s verzí formatteru použitého na serveru a protože ji nalézt nemůže, vyhodí matoucí hlášku, že našel nesmyslnou verzi, jejíž číslo vezme bůhvíkde.
Pastí je v .Net Remotingu více, klidně mi napište, s jakými problémy jste se setkali vy, a já připravím pokračování poradny:)
Sunday, 02 May 2004 18:08:00 (Central Europe Standard Time, UTC+01:00)
.Net Remoting