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
Friday, 30 April 2004
Ztracený potomek se vrací aneb vítejte v Evropě
Stejně jako Radim a další, i já jsem rád, že zítra vstoupíme do EU. Optimisté i skeptici řekli svá někdy zbytečně ostře vyhrocená pro a proti a jistě ve svém zapáleném chrlení argumentů nepřestanou, ale žádně emoce již nemohou na našem zítřejším vstupu do EU nic změnit. I když jsem měl před referendem o vstupu do EU obavu, že český národ dá přednost taktice "máme teď své jisté a po nás potopa", nestalo se tak a přesvědčivá většina řekla vstupu do EU své ano.
Konečně snad můžeme říci, že jsou již definitivně mrtvé nereálné a sebezničující panslavistické obrozenecké koncepty, spoléhající na náruč feudálního Ruska. Tyto koncepty byly s velkou pompou oživeny komunistickými ideology a pohlaváry vrhajícími se do otcovské náruče tatíčka-cara Stalina, která se brzy proměnila v pěst knokautující naší republiku v bezvýznamného červa vydaného na pospas rozmarům senilních oligarchů v Kremlu.
Ani první republika živící sama sebe nadějí, že poloha našeho státu nás předurčuje k tomu být politickým a kulturním pojítkem mezi Východem a Západem, mezi starým a novým světem, dlouho nevydržela. “Státy se udržují idejemi, na kterých byly založeny“, říkal Masaryk. Měl pravdu, když se ukázala iluzornost ideje pojímající republiku jako most mezi Východem a Západem, krátké období samostatnosti skončilo.
Nyní vstupujeme do nové Evropy. Do Evropy poučené kataklyzmaty dvou světových válek a odhodlané nepřipustit opět barbarství komunismu a nacismu. Do Evropy, která je snadným terčem pro kritiky, protože kompromisní hledání nové společné identity respektující rozdílnost států a řešení praktických otázek zohledňující zájmy všech zainteresovaných stran nemůže žehrající maximalisty nikdy uspokojit. Vše velké se rodí v bolestech ani Evropská Unie není výjimkou. Jsem šťastný, že se zítra naplní sen, který předchozím generacím musel připadat v existující politické konstelaci plné nočních můr nesplnitelný. Takový den si naše emoce a radost určitě zaslouží. Od tohoto roku považuji 1. Máj opět za svátek, za svátek EU.:) Užijte si ho.
Friday, 30 April 2004 17:54:00 (Central Europe Standard Time, UTC+01:00)
Ostatní
Thursday, 29 April 2004
Rádio Jerevan?
Ve svém jinak zajímavém weblogu se Tomáš Kouba zamyslel nad úrovní a periodicitou česky psaných zdrojů o .Net platformě. No zamyslel, celý spot na mě působí dojmem, že ho Tomáš Kouba napsal na apríla a opožděně publikoval, ale na konci dubna tenhle spot již opravdu nepobaví.
Co mi tak vadí? Subjektivní dojmy vydávané za podložený názor. Třeba výčet zdrojů o .Net platformě není úplný, byly například opomenuty články na Intervalu o ASP.NET.
Nicméně to není vše, Tomáš Kouba se nám v krátkém příspěvku předvede i jako investigativní novinář, který odhalil skandál okolo nekvalitní práce správců konference Emwac, protože ti jsou údajně sponzorováni Microsoftem za to, že konference bude k něčemu vypadat. Nejde o to, že Microsoft pravděpodobně opravdu Emwacu nějakou částku za hostování platí, ale pochybuji, že pan Kouba má v ruce smlouvu mezi Microsoftem a Emwacem, ve které je napsáno, že za tučný úplatek musí Emwac provozovat konferenci v kvalitě požadované panem Koubou. Takhle vznikají fámy. Nejdříve kdosi vysloví spekulaci, že správci EMWACu jsou za provoz konference placeni Microsoftem (proč ne?) , pak pan Kouba tuto zprávu přijme, ale stále uznává, že jde jen o dohad. Za měsíc a půl již s tou samou spekulací nakládá jako s ověřeným faktem.
Na konci příspěvku Tomáš Kouba přijme roli mudrce, který nám vysvětlí, proč je málo kvalitních článků a blogů pro .Net platformu.
„Je zajímavé, že proti
Javě
je úroveň a především periodicita zdrojů o technologii .NET a C# mnohem horší. Možná je to tím, že ti kteří se živí Microsoft technologiemi mají méně času. Buď je to proto, že programovat pro Microsoft je mnohem náročnější než pro Javu, nebo jsou to obecně komerčněji zaměření lidé. Psaní spotů a článků vyžaduje značnou míru entuziasmu a ten možná Microsoft oblíbencům chybí. Každý máme své priority a na penězích není nic špatného.“
Takže teď jsme se konečně o .Net vývojářích dozvěděli holou pravdu. Jen nevím, co si mám představit pod „komerčněji zaměřeným člověkem“. Asi homo novus, dle všeho pěkná svině:). .Net vývojářům chybí jakékoli nadšení, ale zato jsou to oslíci, kteří na každém kroku trousí prachy ušetřené tím, že svůj čas rozumně neinvestují do psaní článků nebo blogů, protože se nechali poučit, že stejně mají nižší úroveň než články o JAVĚ.
Ten spot nezarazil jen mě, ale třeba i Romana Pichlíka. Tohle jste myslel vážně pane Koubo?
Thursday, 29 April 2004 21:26:00 (Central Europe Standard Time, UTC+01:00)
Ostatní
Pár poznámek k implementaci metody Equals
V poslední době mě docela překvapilo, kolik špatných implementací metody Equals jsem nalezl na webu. Jak jistě víte, metodu Equals mají ve svém rozhraní všechny třídy v .NET Frameworku, protože je deklarována v základní a pro všechny třídy povinné bázové třídě Object. Metoda Equals zjišťuje, zda jsou dvě instance shodné. Ve třídě Object naleznete dvě metody Equals. Instanční virtuální metoda Equals přijímá jeden argument typu Object a její výchozí implementace porovnává referenční identitu dvou instancí. To znamená, že metoda vrátí true pouze tehdy, když porovnává proměnné odkazující na stejné místo v paměti. U hodnotových typů je metoda Equals přepsána tak, že porovnává pomocí reflexe všechny členy instance.
public virtual bool Equals(Object obj);
Pomocné statické metodě Equals se předávají dva argumenty typu object. Metoda nejdříve zkontroluje, jestli je nějaký argument null. Pokud ano, tak metoda vrátí false, jinak zavolá instanční metodu Equals na objektu objA a předá ji objekt v argumentu objB.
public static bool Equals( object objA, object objB);
Ověření, že dvě proměnné ukazují na stejnou instanci, není ale vždy dostačující. V aplikaci potřebujeme často zjistit, zda dvě proměnné ukazující na jinou instanci stejného typu nejsou logicky shodné. Konkrétně, objednávku s číslem 3 můžeme v systému vytvořit ve dvou nezávislých kopiích, ale když porovnáváme proměnné odkazující na tyto nezávislé instance, tak chceme, aby byly instance považovány za shodné. Právě proto musíme správně přepsat metodu Equals a doplnit vlastní porovnávací logiku.
Jak postupovat? Představme si, že chceme přepsat metodu Equals v objektu Order.
public override bool Equals(object obj)
{
}
V těle metody zjistíme, jestli argument obj není null a jestli neni jiného typu, než je typ objektu, na kterém je metoda Equals volána. Jestliže je argument null nebo má odlišný typ, tak ihned vrátíme false, protože nemůžeme porovnávat zcela odlišné nebo neinicializované objekty. Po těchto nutných kontrolách můžeme argument obj bezpečně přetypovat na typ Order a výsledek uložit do proměnné order2.
if (obj == null)
return false;
if (obj.GetType != this.GetType())
return false;
Order order2 = obj as Order;
Když dědíme z jiné třídy než Object, měli bychom zavolat přepsanou metodu Equals bázové třídy. Jestliže metoda Equals bázové třídy vrátí false, musíme z potomka vrátit také false.
Nyní musíme porovnat všechny relevantní soukromé i veřejné členy třídy. Bez ohledu na to, zda porovnáváme hodnotový nebo referenční typ, delegujeme odpovědnost za porovnání na pomocnou statickou metodu Equals třídy Object. Když zjistíme, že někteří členové nejsou shodní, musíme vrátit false. Jestliže se všichni členové shodují, můžeme z metody Equals vrátit true, protože jsme právě ověřili, že obě instance jsou identické.
if (!Object.Equals(this.ReferenceProperty1, order2.ReferenceProperty1))
return false;
if (!Object.Equals(this.ValueProperty2, order2.ValueProperty2))
return false;
return true;
V objektech, které mají jednoznačný identifikátor (Id), metoda Equals často porovná jen identifikátor Id. Porovnání není zcela přesné, protože objekty mohou mít různé hodnoty atributů, ale pro business aplikace je toto porovnání většinou dostačující. U hodnotových typů (struktur) by měla být vytvořena metoda Equals, která příjimá v argumentu přímo hodnotový typ, aby se předešlo boxingu při volání zděděné metody Equals, jež, jak jsme řekli, akceptuje Object. Správně napsaná metoda Equals musí dodržovat následující čtyři pravidla.
1) Musí být reflexivní - porovnám-li instanci A s instancí A, metoda musí vždy vrátit true.
2) Musí být symetrická - jestliže volání metody A.Equals(B) vrátí true, tak B.Equals(A) musí také vrátit true.
3) Musí být tranzitivní - jestliže volání metody A.Equals(B) vrátí true a B.Equals(C) také vrátí true, musí A.Equals(C) vrátit true.
4) Musí být konzistentní - když volání metody A.Equals(B) vrátí true a nedojde ke změně objektu A ani B, tak nové volání A.Equals(B) musí opět vrátit true.
Když máme přepsanou metodu Equals, je výhodné přetížit operátoy rovná se (==) a nerovná se (!=). Implementace je opravdu jednoduchá. Využijeme statickou metodu Object.Equals, která po kontrolách popsaných výše zavolá námi přepsanou instanční metodu Equals, v níž je již obsažena všechna potřebná logika. V operátoru "nerovná se" ještě pochopitelně výsledek metody Equals negujeme.
public static bool operator != (Order order1, Order order2)
{
return !object.Equals(order1, order2);
}
public static bool operator == (Order order1, Order order2)
{
return object.Equals(order1, order2);
}
Thursday, 29 April 2004 19:58:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework
Wednesday, 28 April 2004
Volte nejlepší mobilní telefon na serveru MobilMania
Na serveru Mobilmania vyhlásili každoroční anketu o nejlepší mobilní telefon v kategoriích, rodina, práce, styl a zábava. I když si můžeme myslet o vypovídací hodnotě takových anket své, protože málokterý jejich účastník má možnost i čas otestovat všechny mobily nebo alespoň reprezentativní vzorek a volí tedy většinou telefon, který si koupil, jde o zajímavou hru, která ukazuje, jak si jednotlivé značky na českém trhu stojí a jaká je přibližně jejich penetrace. Poučná bývá také konfrontace výsledků ankety s oficiálními údaji o prodaných telefonech od českých distributorů.
Navíc se dají vyhrát zajímavé ceny, víkend v Římě bych si nechal líbit.:) Tedy jen v případě, že v hotelu bude internetové připojení, protože minulý rok na svatební cestě v Řecku jsem si po prvním týdnu dovolené při prvních abstinenčních příznacích začal stahovat poštu přes vytáčené mobilní připojení. T-Mobile v té době ještě neposkytoval v Řecku GPRS roaming, takže jsem po návratu domů z faktury radost neměl.
Zpět k anketě. Takto jsem volil já.
Nejlepší telefon pro rodinu – Siemens C55. U této kategorie jsem vždy na vážkách, protože vím, že bych měl hlasovat pro funkčně chudé telefony, ale sám žádný takový nepoužívám. Nakonec vyhrál Siemens C55 – jeho vyspělějšího sourozence S55 jsem používal minulý rok a byl jsem spokojen. C55 jsem měl chvíli půjčen od jeho málo náročného uživatele a líbil se mi – slušný černobílý displej, ovládání Siemensu mně vyhovuje, telefon podporuje i Javu (MIDP 1.0), i když má pro ni příliš málo paměti..
Nejlepší telefon pro práci – MDA II. Tady jsem neváhal, lepší přístroj zatím neznám. Až na drobné mušky, jakýmí jsou absence regulace hlasitost vyzváněcí melodie nezávisle na hlasitosti ostatních tónů nebo nemožnost trvale nastavit, že ke každé SMS požaduji doručenku, se jedná o přístroj, který nemá konkurenci. Jak to vypadá, s MDA II ještě nějaký měsíc vydržím. Kromě MDA II se mi také líbí sympaticky baculatá Nokia 6600 se Symbianem a podporou paměťových karet. Jeden z mála modelů, který se Nokii v minulém roce povedl.. Myslím, že telefon bez operačního systému už asi nikdy chtít nebudu.
Nejlepší telefon pro styl a reprezentaci – Siemens SX1. Působivý telefon s OS Symbian, funkčně podobný Nokii 6600, ale dle mého soudu s nepoužitelnou extravagantní klávesnicí. Cílové skupině fajnšmekrů ale určitě na konvenčně a možná až zpátečnicky vnímané ergonomii ovládání příliš nesejde.:)
Nejlepší telefon pro zábavu – N-Gage. Každý se bavíme jinak, ale N-Gage je přes všechnu oprávněnou kritiku zajímavý telefon nebo alespoň zajímavý příslib pro všechny hráče, kterým o funkce mobilního telefonu zase tak nejde. Jen to vyměňování paměťových karet s hrami mohla Nokia vyřešit lépe, šachování s krytem a baterií asi žádného náruživého hráče nenadchne.
V diskuzi můžete napsat, jaké mobilní telefony jste si minulý rok oblíbili Vy. Zajímalo by mě, která značka má mezi technicky orientovanými lidmi nejsilnější pozici, protože mýtus praví, že je to (Sony) Ericsson. Jak je vidět z mého hlasování, kde se SE neobjevil ani jednou, u mě to určitě neplatí. SE sice vyrábí skvělé telefony, ale většinou je shodí nějakým zásadním nedodělkem, jako je pomalé psaní SMS nebo šnečí rychlost celého firmwaru. Mimochodem, nevlastníte někdo SE T610 nebo SE T630? Zajímalo by mě, zda jejich implementace Javy podporuje sokety . Na internetu jsou dost protichůdné informace, takže stále nevím, zda je na ně možné instalovat síťové aplikace. Bez soketů je půvab již tak příliš chudé mobilní Javy zcela ztracen.
Wednesday, 28 April 2004 22:17:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Tuesday, 27 April 2004
Seminář o BizTalku
Dneska jsem skoro celý den strávil na semináři o BizTalku 2004. Dorazil jsem sice s hodinovým zpožděním, protože jsem ráno musel na tradičně neodkladnou analytickou schůzku se zákazníkem, ale díky ní jsem nakonec přišel o zahajovací marketingovou masáž. Štestí v neštěstí. Celý dnešní blok přednášek byl zajímavý, i když vzhledem k rozsahu tématu a nutnosti vysvětlit jej v pouhých dvou dnech je citelně znát, že přednášející odříkává své věty v presu a že všechny vlastnosti BizTalku bez ohledu na jejich složitost musí vysvětlit na jednom zjednodušujícím slidu prezentace. Škoda, ale samostudium technologií je stejně dobrodružnější. ;)
Na BizTalku je nejzajímavější abstrahování od nízkoúrovňových implementačních záležitostí, jakými jsou ruční návrh XSD schémat nebo infrastruktura pro business procesy. Ve vizuálním režimu se dá navrhnout většina typických transformací a translací dat, je snadné rychle rozehrát sladěný orchestr různých business procesů, aniž bych musel měsíce trávit vývojem a testováním potřebných komponent.
Kdy a proč jsem se začal o BizTalk zajímat? Prvotním motivem bylo zjištění, že naší zákazníci si pod pro mě jednoznačnou zkratkou CRM představují systém, do nějž budou integrována všechna jejich data z přehršle různých systémů pracujících nad různými databázemi, které si každé oddělení firmy nechalo z vlastní ďábelské iniciativy vyvinout. Když ale chce top management firmy vidět souhrnná data o zákaznících ze všech systémů, tak se teprve ukáže, že ďábelská iniciativa nezbytně formuje jen celofiremní SW peklo. Jak data ze systémů získat? Kam je uložit? Jak zajistit jejich konzistenci? Není lepší datové sady i za cenu vyšší časové náročnosti integrovat online na požádání uživatele? To jsou jen jemné náznaky nepříjemných problémů čekajících na řešení.
Pro náš CRM systém E-Dirigent jsem navrhl snadno rozšiřitelnou vrstvu datových konektorů s jednoduchým veřejným rozhraním, ve které jsou všechny rozdíly při komunikaci s heterogenními datovými zdroji centralizovány, a zbylé vrstvy aplikace si nejsou vědomy, že komunikují například s WWW službou místo s výchozím MSSQL serverem. Problémy, které se musí řešit při online komunikaci s datovými zdroji nejsou příjemné - jen namátkou:
- Jak provést JOIN nad zdrojem, jenž JOIN nepodporuje?
- Co s agregačními funkcemi, které mají pracovat nad více datovými zdroji?
- Jak zajistit aktualizaci údajů napříč datovými zdroji v jediné transakci?
Nakonec funkční a relativně jednoduchý návrh vznikl. Protože si ale samozřejmě nemůžeme dovolit vyvinout úplně univerzální řešení, tak je návrh prošpikován kompromisy (tohle slovo opravdu nemám rád), a proto jsem se stále více přikláněl a přikláním k tomu, že na takové záležitosti je lepší u zákazníka nasadit vyzkoušený a fexibilní BizTalk. Mohu se ale mýlit. Budu rád, když mě poučí někdo, kdo BizTalk na Enterprise integrace používá. Je vůbec v Čechách někdo takový?
Tuesday, 27 April 2004 20:52:00 (Central Europe Standard Time, UTC+01:00)
Biztalk
UML 2.0 - zastavení první
Se snad blížícím se datem uvolnění finální verze 2.0 jazyka UML je myslím přínosné popsat mé první zkušenosti s novou verzí. Myslím, že se druhá verze jazyka UML stejně jako verze 1.0 stane nepřehlédnutelným periodizačním mezníkem v oblasti analýzy a vývoje softwaru. S uvedením první verze jazyka UML v roce 1996 skončilo neplodné období válek mezi vzájemně se potírajícími metodikami a jejich občas málo soudnými tvůrci, kteří by pravděpodobně nejraději své výtvory šířili s pěnou "u huby" ohněm i mečem. Málokdo také tušil, že UML předznamenává novou epochu. Epochu, v níž znalost UML je povinností nejen pro analytiky a designéry, ale alespoň pasivní znalost se předpokládá také u vývojáře, jehož nejvyšší pracovní ambicí není kreativní psaní formulářů na editaci číselníků. Nic na tomto světě není nikdy perfektní a i pro UML po sérii dílčích vylepšení, jež vyústily ve verzi 1.5, nadešel čas na nový velký "release“ zaměřený na zacelení dlouhodobě pociťovaných mezer ve specifikaci, které se staly neblahým impulsem pro vznik proprietárních rozšíření. Tato rozšíření se zaměřovala hlavně na silnější podporu analytika modelujícího dynamické chovaní systémů. Three amigos vrací úder a odvrací hrozbu nového vysilujícího souboje disparátních specifikací vylepšeními ve verzi 2.0 jazyka UML. Vylepšeny byly nejen diagramy pro dynamické chování, ale byly také přidány zcela nové diagramy (Composite structure diagram, Timing diagram, Interaction overview diagram) a rozšířeny takřka všechny ostatní a z verzí 1.x známé strukturní prvky.
Dnes se podíváme na vylepšení případů užití (Use Case), ve kterých ale k žádným velkým změnám nedošlo, protože jejich hlavním účelem je vizualizovat funkční rozsah systému pro zákazníka a tak by příliš mnoho fines, ornamentů a vychytávek mohlo smysl diagramu spíše zatemnit. Případy užití jsou přesto ve verzi 2.0 více provázány s ostatními diagramy, aby model systému působil kompaktnějším dojmem.
- Kromě seskupování případů užití do balíčků, je možné je nyní seskupit v klasifikátoru. Toho využijeme například tehdy, když budeme psát informační systém pro velkou společnost a v modelu bude klasifikátor divize vyjadřující rozdělení společnosti do menších celků. Jestliže se liší případy užití realizované zaměstnanci různých divizí, například divize finanční a divize technologické, můžeme z důvodu větší názornosti klasifikovat případy užití jejich seskupením pod jednotlivé divize.
- U vztahu Extend mezi případy užití je doporučeno zachytit podrobnosti rozšíření v poznámce (Note). Poznámka by měla mít strukturu:
Condition:[Podmínka, při které nastane rozšíření]
Extension Point:[Bod rozšíření]
- Když případ užití obsahuje větší množství bodů rozšíření, je možné pro jeho vyjádření použít alternativní symbol. Symbolem je obdélník, který je rozdělen nepřerušovanou čarou na dvě části. V horní části je jméno případu užití a ovál, který je tradičním symbolem případu užití. Ve spodní části se nachází seznam bodů rozšíření.
- Případ užití může nyní “vlastnit” jiný diagram. Příkladem může být stavový diagram popisující průběh vyřizování objednávky u případu užití s názvem zpracování objednávky. Vložené diagramy nejsou určeny pro zákazníka, ale pro rychlé zachycení složitých vazeb mezi různými částmi modelu budou neocenitelné.
Monday, 26 April 2004 23:01:00 (Central Europe Standard Time, UTC+01:00)
UML
Sunday, 25 April 2004
Výběr ze seznamu Id serverových ovládacích prvků na stránce
V konferenci EMWAC se objevil příspěvek http://konference.vyvojar.cz/post.aspx?id=53046, jehož autor chce do vlastnosti ve svém serverovém ovládacím prvku uložit Id jiného ovládacího prvku na stránce. Vývojář by neměl zapisovat Id přímo, ale vybírat ze seznamu na stránce vlastností. První myšlenkou autora příspěvku bylo nadeklarovat vlastnost jako WebControl - to je samozřejmě nesmysl. Když zkusíme perzistovat vlastnost na stránce (atribut PersistenceMode), tak dosáhneme pouze toho, že validátor ASPX stránky nás bude upozorňovat, že máme na stránce 2 prvky se stejným Id.
To, o co se autor snaží, umí všichni validátoři. Jejich vlastnost ControlToValidate nabídne Id všech prvků na stránce, kteří obsahují vlastnost dekorovanou atributem ValidationProperty. Vlastnost ControlToValidate je samozřejmě typu string. Seznam Id naplní speciální TypeConverter s názvem ValidatedControlConverter.
ValidatedControlConverter nelze použít pro načtení seznamu Id všech prvků na stránce, protože, jak jsem již napsal, ta bere v úvahu jen prvky s vlastností označenou atributem ValidationProperty. Proto jsem napsal ControlConverter, který nalezne Id všech prvků na stránce.
public
class
ControlConverter : StringConverter
{
public
ControlConverter() :
base
()
{
}
public
override
StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
if
((context ==
null
) || (context.Container ==
null
))
return
null
;
object
[] foundControls = enumerateControls(context.Container);
if
(foundControls ==
null
)
return
null
;
return
new
StandardValuesCollection(foundControls);
}
public
override
bool
GetStandardValuesSupported(ITypeDescriptorContext context)
{
return
true
;
}
public
override
bool
GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return
false
;
}
private
object
[] enumerateControls(IContainer container)
{
ArrayList retList = new ArrayList();
foreach
(IComponent component
in
container.Components)
{
Control foundControl = component as Control;
if
(foundControl ==
null
)
continue
;
if
((foundControl.ID ==
null
) ||
(foundControl.ID == String.Empty))
continue
;
retList.Add(foundControl.ID);
}
return
retList.ToArray();
}
}
Converter se u vlastnosti použije takto:
[Browsable(
true
)]
[TypeConverter(
typeof
(ControlConverter))]
public
string
MyControl
{
get
{
string
myControl = (
string
) ViewState["MyControl"];
return
(myControl ==
null
? String.Empty : myControl);
}
set
{
ViewState["myControl"] =
value
;
}
}
Sunday, 25 April 2004 18:44:00 (Central Europe Standard Time, UTC+01:00)
ASP.NET | .NET Framework