<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.aspnet.sk/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Skippov blog</title><link>http://blog.aspnet.sk/skippo/default.aspx</link><description>Pre Vas. Pre mna. Pre dalsie generacie.</description><dc:language>sk-SK</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Spring.NET a podpora NHibernate</title><link>http://blog.aspnet.sk/skippo/archive/2010/01/04/spring-net-a-podpora-nhibernate.aspx</link><pubDate>Mon, 04 Jan 2010 10:09:00 GMT</pubDate><guid isPermaLink="false">cbdfeddd-8b45-43cb-b10b-361e40cba84b:220253</guid><dc:creator>skippo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.aspnet.sk/skippo/rsscomments.aspx?PostID=220253</wfw:commentRss><comments>http://blog.aspnet.sk/skippo/archive/2010/01/04/spring-net-a-podpora-nhibernate.aspx#comments</comments><description>&lt;p&gt;Nedavno sa mi pod ruky dostala celkom nahodou (trosku starsia)&amp;nbsp;prezentacia Thomasa Hauga o kniznici Spring.NET; &lt;br /&gt;&lt;a href="http://www.springframework.net/presentations/SpringNet-ThomasHaug-2008.pdf"&gt;http://www.springframework.net/presentations/SpringNet-ThomasHaug-2008.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Vacsina pouzivatelov vratane mna najviac vyuziva core functionalitu a to IoC kontajner. Na co som bol zvedavy, je podpora inych kniznic a toolov, najma NHibernate.&lt;/p&gt;
&lt;p&gt;Potesila ma podpora DAO patternu, nasledujuci priklad priamo z prezentacie:&lt;/p&gt;
&lt;p&gt;using Spring.Data.NHibernate.Generic.Support;&lt;br /&gt;...&lt;br /&gt;class NHibernatePersonDAO : HibernateDaoSupport, IPersonDAO {&lt;br /&gt;&amp;nbsp; public void SavePerson(SpringBeispiel.Entities.Person person){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //wirft eine Spring.Dao.DataAccessException&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //falls ein Fehler auftritt&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.HibernateTemplate.Save(person);&lt;br /&gt;&amp;nbsp; }&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp; public IList&amp;lt;Person&amp;gt; ListPersons() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return HibernateTemplate.LoadAll&amp;lt;Person&amp;gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; public void UpdatePerson(Person person) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.HibernateTemplate.Update(person);&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;A priklad na servis s podporou transakcii:&lt;/p&gt;
&lt;p&gt;using Spring.Transaction.Interceptor;&lt;br /&gt;...&lt;br /&gt;class PersonServiceImpl : IPersonService {&lt;br /&gt;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;[Transaction(Timeout=1000)]&lt;br /&gt;&amp;nbsp;public void RenameLastName(Person p1, Person p2, string lastName) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;p1.Nachname = lastName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;p2.Nachname = lastName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;this.personDAO.UpdatePerson(p1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;this.personDAO.UpdatePerson(p2);&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;[Transaction(ReadOnly=true)]&lt;br /&gt;&amp;nbsp;public IList&amp;lt;Person&amp;gt; ListPersons()&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;return this.personDAO.ListPersons();&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;Je dobre vediet, ze spring so sebou prinasa aj takuto existujucu infrastrukturu. Vedel by som si predstavit jej vyuzitie aj pri implementacii Repository design patternu zalozenej na NH, kde by sme sa vyhli vyvoju+testovaniu infrastruktury ziskavania session a&amp;nbsp;podporu transakcii. Vyskusam a dam vediet.&lt;/p&gt;
&lt;p&gt;pre pouzivatelov springu, nezabudnite checknut instalacny .zip archiv a nainstlaovat podporu pre VS, Resharper, xsd schemy, atd.&lt;/p&gt;
		&lt;script src="http://connect.facebook.net/en_US/all.js#xfbml=1"&gt;&lt;/script&gt;&lt;fb:like href="" show_faces="true" width="450" font=""&gt;&lt;/fb:like&gt;&lt;img src="http://blog.aspnet.sk/aggbug.aspx?PostID=220253" width="1" height="1"&gt;</description><category domain="http://blog.aspnet.sk/skippo/archive/tags/Design+Patterns/default.aspx">Design Patterns</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/Repository/default.aspx">Repository</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/DAO/default.aspx">DAO</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/Spring.NET/default.aspx">Spring.NET</category></item><item><title>NHibernate: presnost ulozenia DateTime typu</title><link>http://blog.aspnet.sk/skippo/archive/2009/09/08/nhibernate-presnost-ulozenia-datetime-typu.aspx</link><pubDate>Tue, 08 Sep 2009 07:00:00 GMT</pubDate><guid isPermaLink="false">cbdfeddd-8b45-43cb-b10b-361e40cba84b:129673</guid><dc:creator>skippo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.aspnet.sk/skippo/rsscomments.aspx?PostID=129673</wfw:commentRss><comments>http://blog.aspnet.sk/skippo/archive/2009/09/08/nhibernate-presnost-ulozenia-datetime-typu.aspx#comments</comments><description>&lt;p&gt;Ak potrebujete ulozit typ DateTime s presnostou na milisekundy (napr ukladam transakcie a tam potrebujem co najvyssiu presnost), moze byt neprijemne zistit, ze NHibernate v kombinacii s MSSQL serverom (a tipujem, ze&amp;nbsp;sa to tyka aj dalsich db serverov)&amp;nbsp;vam milisekundovu cast jednoducho odsekne. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Preco sa to deje? Nativny .NET DateTime typ uklada cas - konkretne milisekundy s presnostou na 7 miest. MSSQL nativny DateTime iba 3 (DateTime2 uz na 7, vid t-sql msdn doc: &lt;a href="http://msdn.microsoft.com/en-us/library/ms187819.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms187819.aspx&lt;/a&gt;). NH standardne pouziva ADO.NET pre komunikaciu s MSSQL, a ten nam nic presnejsie ako mu databaza ponuka nevrati. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Kvoli tymto rozdielom NH odsekava milisekundovu cast a nechava tuto funkcnost na uzivatela. &lt;/p&gt;
&lt;p&gt;Mozne riesenia: &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1) ako prve by nas napadlo ukladat ticks ako Int64 - to zafunguje, avsak niekedy chceme mat cas ulozeny ako DateTime (napriklad pri rieseni problemov, ak mame logy (napr transakcii), jazyk SQL a databaza nam umozni komfortne a rychlo vyhladat problemove zaznamy). &lt;/p&gt;
&lt;p&gt;2) slo by to za pouzitia Interceptorov, toto riesenie sa mi zda nevhodne, smrdi. Overridnut OnSave, OnFlushDirty... &lt;/p&gt;&lt;pre&gt;public override bool OnFlushDirty(object entity, 
                                  object id, 
                              object[] currentState,
                              object[] previousState, 
                              string[] propertyNames,
                              IType[] types) 
{
    if(entity is DomainObjectICareAbout)
        for ( int i=0; i &amp;lt; propertyNames.Length; i++ ) {
            if ( currentState[i] is DateTime ) {
                DateTime dt = (DateTime)currentState[i];
                dt = dt.AddMilliseconds(-1 * dt.Millisecond);
                return true;
            }
        }
    }
    return false;
}

&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;3) session.Refresh(entity) by malo zafungovat akurat je to extra query. &lt;/p&gt;
&lt;p&gt;4) vlastny typ - implementovat IUserType, co sa mi zda najvhodnejsie riesenie. &lt;/p&gt;
&lt;p&gt;Pekny post som nasiel tu: &lt;a href="http://www.mostlyclean.com/post/2007/11/Increasing-DateTime-storage-precision-in-Nhibernate-(and-Castle-ActiveRecord).aspx"&gt;http://www.mostlyclean.com/post/2007/11/Increasing-DateTime-storage-precision-in-Nhibernate-(and-Castle-ActiveRecord).aspx&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Z clanku ukazka: &lt;/p&gt;&lt;pre&gt;public class PreciseDateTimeUserType : IUserType
    {
        #region IUserType Members

        ......

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            int ordinal = rs.GetOrdinal(names[0]);
            if (rs.IsDBNull(ordinal))
            {
                return new NullPreciseDateTime();
            }
            else
            {
                long value = rs.GetInt64(ordinal);
                return new PreciseDateTime(value);
            }
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            long val = ((PreciseDateTime) value);
            ((IDbDataParameter) cmd.Parameters[index]).Value = val;
        }

        .....

        #endregion
    }
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Je tam priklad tak pre NH ako aj CastleRecord. &lt;/p&gt;
		&lt;script src="http://connect.facebook.net/en_US/all.js#xfbml=1"&gt;&lt;/script&gt;&lt;fb:like href="" show_faces="true" width="450" font=""&gt;&lt;/fb:like&gt;&lt;img src="http://blog.aspnet.sk/aggbug.aspx?PostID=129673" width="1" height="1"&gt;</description><category domain="http://blog.aspnet.sk/skippo/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/ActiveRecord/default.aspx">ActiveRecord</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/MSSQL/default.aspx">MSSQL</category></item><item><title>Logovanie: Enterprise Library versus POCO&amp;Dependency Inversion[Spring]</title><link>http://blog.aspnet.sk/skippo/archive/2009/09/03/logovanie-enterprise-library-versus-poco-amp-spring-net.aspx</link><pubDate>Thu, 03 Sep 2009 15:09:00 GMT</pubDate><guid isPermaLink="false">cbdfeddd-8b45-43cb-b10b-361e40cba84b:129392</guid><dc:creator>skippo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.aspnet.sk/skippo/rsscomments.aspx?PostID=129392</wfw:commentRss><comments>http://blog.aspnet.sk/skippo/archive/2009/09/03/logovanie-enterprise-library-versus-poco-amp-spring-net.aspx#comments</comments><description>&lt;p&gt;Enterprise library je kolekcia znovu pouzitelnych a kombinovatelnych kniznic od Microsoftu roznej funkcionality (data access, logging, exception handling, caching, crypto, validation, security, atd) s cielom pouzia (nie len) vo vacsich projektoch. Kazda kniznica riesiaca isty problem sa nazyva blok a tieto bloky mozete nakombinovat az postavite pekny (lego) domcek. Posledna verzia bola vydana v oktobri 2008 a nesie verziu 4.1 (aj ked z vacsej casti obsahuje bugfixy a vylepsenie vykonnosti, preto ak pouzivate starsiu verziu, rozhodne doporucujem upgrade).&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc467894.aspx" target="_blank"&gt;http://msdn.microsoft.com/en-us/library/cc467894.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Spring.NET je trosku mensi moloch, obsahujuci okrem ineho aj IoC kontajner (alebo Dependency Inversion, ako sa Vam paci). Je vyvyjany ako open source a mometalna stabilna verzia je 1.2.0 aj ked 1.3.0 je vo verzii RC a coskoro sa dockame final release.&lt;br /&gt;&lt;a href="http://www.springframework.net/" target="_blank"&gt;http://www.springframework.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Enterprise Library Logging Block&lt;/span&gt;&lt;br /&gt;EL obsahuje Logging block zodpovedny za logovanie a snazi sa nam integraciu co najviac ulahcit. Architektura je zalozena na pouziti trace listenerov (podobne ako to pozname z .NET a jeho tracing funkcionality).&lt;br /&gt;Zakladne a zjednodusene kroky pre integrovanie logging bloku:&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nareferencujeme prislusne kniznice (Common a Logging z EL by mali stacit)&lt;/li&gt;

&lt;li&gt;nakonfigurujeme kategorie (xml), do ktorych budeme logovat&lt;/li&gt;

&lt;li&gt;nakonfigurujeme (xml), ktore trace listenery chceme pouzit (tu mame na vyber z viacerych pripravenych, vratane event log, e-mail, db, message queue, subor, WMI alebo vlastny trace listener.&lt;/li&gt;

&lt;li&gt;V kode vytvorime instanciu EventLog triedy, naplnime datami, ktore by sme radi zalogovali a zavolame staticku metodu Write Enterprise library.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Priklad pouzitia&lt;br /&gt;var entry = new LogEntry()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // init&lt;br /&gt;};&lt;br /&gt;Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(entry);&lt;/p&gt;

&lt;p&gt;Zjednoduseny priklad konfiguracie (2 kategorie, druha loguje len do suboru, event log trace listener loguje len spravy s typom error a vyssie).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;loggingConfiguration name=&amp;quot;Logging Application Block&amp;quot; tracingEnabled=&amp;quot;true&amp;quot;&lt;br /&gt;&amp;nbsp; defaultCategory=&amp;quot;&amp;quot; logWarningsWhenNoCategoriesMatch=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;listeners&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fileName=&amp;quot;trace.log&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; formatter=&amp;quot;Text Formatter&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; listenerDataType=&amp;quot;FlatFileTraceListenerData”&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; traceOutputOptions=&amp;quot;None&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filter=&amp;quot;All&amp;quot;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name=&amp;quot;FlatFile TraceListener&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; source=&amp;quot;Enterprise Library Logging&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; formatter=&amp;quot;Text Formatter&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; log=&amp;quot;Application&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; machineName=&amp;quot;&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; listenerDataType=&amp;quot;FormattedEventLogTraceListenerData&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; traceOutputOptions=&amp;quot;None&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filter=”Error&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name=&amp;quot;Formatted EventLog TraceListener&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/listeners&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;formatters&amp;gt; … &amp;lt;/formatters&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;categorySources&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add switchValue=”All” name=”Errors”&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;listeners&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name=”Formatted EventLog TraceListener” /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name=” FlatFile TraceListener” /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/listeners&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/add&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add switchValue=”All” name=”User Transactions”&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;listeners&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name=” FlatFile TraceListener” /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/listeners&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/add&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/categorySources&amp;gt;&lt;br /&gt;&amp;lt;/loggingConfiguration&amp;gt;&lt;br /&gt;&lt;/p&gt;Z hore uvedeneho je jasne, ze EL Logging Block nam ponuka out-of-box riesenie, lahko integrovatelne a plne konfigurovatelne. Vo vaccine pripadov budeme chciet vytvorit vlastny trace listener, pretoze zabudovane listeneri nam nebudu stacit. &lt;br /&gt;&lt;br /&gt;Budeme potrebovat podedit od triedy CustomTraceListener, odekorovat novu triedu atributom [ConfigurationElementType(typeof(CustomTraceListenerData))] a overridnut metodu TraceData (podla toho, co potrebujeme). Jej telo bude obsahovat nasu logiku pre spracovanie instancie LogEntry (napriklad ulozenie do db, odoslanie sms, a pod), ktora do metody prichadza ako parameter.&lt;br /&gt;Zatial vsetko dobre. Kde to zacina haprovat je vykon. Ak vyvyjate aplikaciu, ktora si musi frcat (typicky priklad obsluhovat xyz requestov za sekundu), Logging blok nebude dobra volba. Nedavno sme stresstestovali jeden nas live webservis, kde sme pouzili prave logging blok a boli sme zial nemilo prekvapeny vysledkami. Co to som sa docital na webe ako je architektura az priliz komplikovana, ale tie cisla boli naozaj prekvapujuce.&lt;br /&gt;&lt;br /&gt;Ako sme testovali? &lt;br /&gt;Separatna siet, dedikovane databazy a 2 webservre a load balancer (aby sme sa co najviac priblizili k live enviromentu). webservis robi pomerne komplikovane penazne transakcie a je sucastou distribuovanych transakcii cez http, takze vykon je v nasom pripade ziaduci. Servis obsahuje niekolko funkcii, kazda rozne zatazuje system, od loginu az po samotne transakcie. Cely test bezal 3 hodiny.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Orientacne vysledky&lt;/b&gt;&lt;br /&gt;Priemerny pocet obsluzenych req/s (vsetky metody) s Logging blokom: 211&lt;br /&gt;Priemerny pocet obsluzenych req/s (vsetky metody) cez Logging bloku: 272&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Kde je uzke miesto?&lt;/b&gt;&lt;br /&gt;Este doplnim, ze odhalenie uzkeho miesta nebolo az take trivialne, nakolko na aplikacii prebehol pomerne rozsiahly refactoring logovania, ktory predstavil enterprise library a z pociatku nebolo jasne, v com je problem. A tak prisiel cas pre .NET profiler a JetBrains dotTrace, vynikajuci tool, vrele doporucujem.&lt;br /&gt;&lt;br /&gt;dotTrace odhalil, ze komunikacia v bode, ked loging bloku posleme objekt na zalogovanie do prislusnych trace listenerov (v nasom pripade to bola len databaza) trva velmi dlho. Cisla, ktore odhalil profiling:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;60 volani Write statickej metody Loging bloku trvalo 16.254ms (2,32% celkoveho casu)&lt;/li&gt;&lt;li&gt; 60 volani pripojeneho trace listenera (v ramci volanej metody Write), ktory data zapisal do databazy bolo dokopy 4.748ms (0,68% celkoveho casu)&lt;/li&gt;&lt;/ul&gt;Niekde sa nam straca viac ako 10.000ms, to je skutocne obrovske cislo.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Poucenie&lt;/b&gt;&lt;br /&gt;Nakolko niektore bloky EL sa vo firme uspesne pouzivaju a samotny logging blok pouziva niekolko release teamov, boli sme malo opatrni a vyuzili predpripravene triedy a funkcnost ako priamu zavislost. Najma ked sa jednalo len o obycajne logovanie. Vymenit EL za nieco ine nebolo az take narocne, nakolko predchadzajuci refactoring vyriesil mnohe problemy a odtienil ostatnu cast kodu od implementacie logovania, ale aj tak sme si mohli usetrit cas odstranenim tejto zavislosti. Takze minimalizovat zavislosti aj od relativne nekomplikovanych casti programu. A teda interfaces a IoC.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Riesenie&lt;/b&gt;&lt;br /&gt;Implementovali sme vlastny jednoduchy loging blok. Mozno to znie divne, ale zvazme fakty:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; implementacia vznikla uz v ramci odhalenia vykonnostnych problemov loging bloku&lt;/li&gt;&lt;li&gt;custom trace listner sme mali implementovany&lt;/li&gt;&lt;li&gt; vykon&lt;/li&gt;&lt;li&gt; vyberat a testovat ine existujuce frameworky, ktore navyse vo velkej firme ako nasa musi schvalit ista rada architektov, dalsie polienko pod nohy&lt;/li&gt;&lt;li&gt; mame k dispozicii IoC kontajner&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Ked sa tak pozrieme na hore popisany logging block z EL (a ostatny frameworky na tom budu nejako podobne), vacsinu funkcionality resp konfiguracie je napisana prave v .xml subore. Pockat, co nam este umoznuje pripravit nieco podobne? Nainicializovat a vratit objekt daneho typu. Ano spravne, IoC kontajner. V nasom pripade spring.net. V samostatnom subore nakonfigurujeme de facto to iste ako v konfiguracnom subore loging bloku.&lt;br /&gt;&lt;br /&gt;V kode potom vytvorime 2 interfaces:&lt;br /&gt;

&lt;pre&gt;public interface ILoggingBlock&lt;br /&gt;{&lt;br /&gt;	void Write(LogEntry data);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface ITraceListener&lt;br /&gt;{&lt;br /&gt;	void TraceData(LogEntry data);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;LogEntry bude nasa classa, mozeme sa inspirovat existujucimi rieseniami, napriklad takto:&lt;br /&gt;

&lt;pre&gt;public class LogEntry&lt;br /&gt;{&lt;br /&gt;	public LogEntry()&lt;br /&gt;	{&lt;br /&gt;		this.Severity = TraceEventType.Error;&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	public object Data { get; set; }&lt;br /&gt;&lt;br /&gt;	public string Title { get; set; }&lt;br /&gt;&lt;br /&gt;	public string Message { get; set; }&lt;br /&gt;&lt;br /&gt;	public TraceEventType Severity { get; set; }&lt;br /&gt;&lt;br /&gt;	public int EventId { get; set; }&lt;br /&gt;&lt;br /&gt;	public ICollection Categories { get; set; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;Pricom do property Data si mozeme poslat nase custom data, ktore potom trace listner ulozi do db.&lt;br /&gt;&lt;br /&gt;Ako bude vyzerat samotny logging blok, ktory okrem trace listeners podporuje aj kategorie? V jednoduchosti je krasa:&lt;br /&gt;

&lt;pre&gt;public class LoggingBlock : ILoggingBlock&lt;br /&gt;{&lt;br /&gt;	public LoggingBlock(IDictionary&amp;gt; traceCategories)&lt;br /&gt;	{&lt;br /&gt;		this.TraceCategories = traceCategories;&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	#region Props&lt;br /&gt;&lt;br /&gt;	protected IDictionary&amp;gt; TraceCategories { get; set; }&lt;br /&gt;&lt;br /&gt;	public int TraceListenerFailedEventId { get; set; }&lt;br /&gt;&lt;br /&gt;	#endregion&lt;br /&gt;&lt;br /&gt;	#region ILoggingBlock Members&lt;br /&gt;&lt;br /&gt;	public void Write(LogEntry data)&lt;br /&gt;	{&lt;br /&gt;		foreach ( string category in data.Categories )&lt;br /&gt;		{&lt;br /&gt;			if ( !this.TraceCategories.ContainsKey(category) )&lt;br /&gt;			{&lt;br /&gt;				throw new Exception(&amp;quot;Logging configuration does not contain category: &amp;quot; + category);&lt;br /&gt;			}&lt;br /&gt;&lt;br /&gt;			var traceListeners = this.TraceCategories[category];&lt;br /&gt;&lt;br /&gt;			foreach ( var tl in traceListeners )&lt;br /&gt;			{&lt;br /&gt;				try&lt;br /&gt;				{&lt;br /&gt;					tl.TraceData(data);&lt;br /&gt;				}&lt;br /&gt;				catch ( Exception ex )&lt;br /&gt;				{&lt;br /&gt;					System.Diagnostics.EventLog.WriteEntry(&lt;br /&gt;						&amp;quot;My Logging Block&amp;quot;&lt;br /&gt;						, &amp;quot;Warning: trace listener failed (&amp;quot;&lt;br /&gt;							+ ex.Message&lt;br /&gt;							+ &amp;quot;). Logging to other trace listeners will continue.”&lt;br /&gt;							+ Environment.NewLine&lt;br /&gt;							+ &amp;quot;Category: &amp;quot; + category&lt;br /&gt;							+ Environment.NewLine&lt;br /&gt;							+ ex.ToString()&lt;br /&gt;							, EventLogEntryType.Error&lt;br /&gt;							, TraceListenerFailedEventId&lt;br /&gt;						);&lt;br /&gt;				}&lt;br /&gt;			}&lt;br /&gt;		}&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	#endregion&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;A co trace listeners? Staci implementovat interface ITraceListener a v pripade napr windows event logu pouzit .NET building metodu System.Diagnostics.EventLog.WriteEntry(..). Cela praca na niekolko minut. Jedina komplikovanejsia cast ostava nakonfigurovanie IoC kontajnera. Ak ho v teame pouzivate, tak je to tiez brnkacka a vysledok bude prudko totozny z hore uvedenou konfiguraciou z EL. V buducnosti ak budeme chciet vymenit nas loging blok za nieco sofistikovanejsie, implementujeme interface ILoggingBlock a v konfiguracii IoC nastavime prislusne referencie a typy. To nam umozni menit loging bloky za behu, co je velmi pekne najma pocas stress testov adeptov na novu implementaciu funkcnosti. Samozrejme hore uvedena implementacia je trivialna ale je na com stavat. S pomocou IoC kontajnera nie je problem doplnit Filtre pre rozny typy LogEntry (error, warning, information, critical), event id pre jednotlive typy (aby napr nas MOM system vedel rozposlat varovne emaily, kde sa zaloguje vynimka (error) a pod). A to uz smeruje k pravdepodobne nejakemu peknemu existujucemu rieseniu, zalezi co aplikacia potrebuje. Pre nase servisy zatial viac nepotrebujeme a rychlost a jednoduchost je vyborna. Ak bude treba, vieme existujuce riesenie lahko integrovat a otestovat v porovnani s existujucim. &lt;br /&gt;&lt;br /&gt;Na tomto mieste by som rad spomenul este jedno poucenie. Cele nastudovanie enterprise library, jej upgrade v ramci celej firmy z 4.0 na 4.1 (bug v buildin event log trace listeneri), jej integrovanie a konfigurovanie, testovanie a profilovanie zabralo pomerne dost casu oproti alternativnemu prezentovanemu rieseniu, resp obdobnej alternativy. 4.0 -&amp;gt; 4.1: dalsia nevyhoda uzavreteho projektu, kde cakame rok na opravenie banalnej chyby.&lt;br /&gt;&lt;br /&gt;Vysledky reprezentuje druha hodnota zo stresstestov bez EL. Volania medzi ILoggingBlock a ITraceListener su standardne dlhe ako bezna komunikacia (s pretypovanim) v .NET. Priznam sa, ze neviem a ani sa mi to nechce zistovat, co sposobuje take zle casy v pripade EL.&lt;br /&gt;&lt;br /&gt;Uceleny zoznam logovacich frameworkov mozeme najst napr tu:&lt;br /&gt;&lt;a href="http://www.dotnetlogging.com/" target="_blank"&gt;http://www.dotnetlogging.com/&lt;/a&gt;&lt;br /&gt;Treba mat ale vzdy napamati rozsiritelnost, vykon, konfigurovatelnost, zdrojaky (opensource), aktivita v komunite. Opravte ma ak sa mylim, ale taky popularny log4net trochu zaspal dobu. Ake su vase skusenosti s logovacimi frameworkami?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Zaver&lt;/b&gt;&lt;br /&gt;Snazil som sa poukazat len na jedno z mnohych peknych vyuzitii IoC kontajnerov a vykonnostny problem Logging Blocku Enterprise library. Ako dalej zvysit rychlost logovania, ak je napr databaza bottleneck v pripade, ze musime toho logovat velmi vela (napr kvoli zakonom v danej krajine) za pouzitia messaging servisov (TIBCO, MSMQ) snad nabuduce. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;

		&lt;script src="http://connect.facebook.net/en_US/all.js#xfbml=1"&gt;&lt;/script&gt;&lt;fb:like href="" show_faces="true" width="450" font=""&gt;&lt;/fb:like&gt;&lt;img src="http://blog.aspnet.sk/aggbug.aspx?PostID=129392" width="1" height="1"&gt;</description></item><item><title>Prakticke problemy pri konvertovani mien pomocou datoveho typu Double</title><link>http://blog.aspnet.sk/skippo/archive/2008/12/11/prakticke-problemy-pri-konvertovani-mien-pomocou-datoveho-typu-double.aspx</link><pubDate>Thu, 11 Dec 2008 08:59:00 GMT</pubDate><guid isPermaLink="false">cbdfeddd-8b45-43cb-b10b-361e40cba84b:55429</guid><dc:creator>skippo</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.aspnet.sk/skippo/rsscomments.aspx?PostID=55429</wfw:commentRss><comments>http://blog.aspnet.sk/skippo/archive/2008/12/11/prakticke-problemy-pri-konvertovani-mien-pomocou-datoveho-typu-double.aspx#comments</comments><description>&lt;p&gt;Zacnime vtipom:&lt;/p&gt;&lt;p&gt;&lt;i&gt;&amp;quot;Rada nad zlato.

Chcete zvacsit svoj kapital?



Pozerajte si vyplatu pod lupou.&amp;quot;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Skippova poznamka: &amp;quot;&lt;i&gt;najma po 1. januari 2009&lt;/i&gt;&amp;quot; :-)&lt;/p&gt;&lt;p&gt;Kazdy programator sa skor ci neskor dostane do kontaktu s aplikaciou, ktora naraba s peniazmi. Peniaze su citliva tema, najma ak sa dostane na ich reprezentaciu v pocitaci, ktory ma obmedzenu pamat (-:jedina nekonecna vec by mala byt ludska hlupost:-). Nedavno som opravoval par problemom suvisiacich s konverziou penazi do roznych mien a teraz sa mi naskytlo trosku casu to nejako zosumarizovat. Niektore veci su trivialne, ine trosku menej, nic-menej vsetko, co suvisi s peniazmi (klientov) je dolezite. Ked som problem videl prvy krat na obrazovke, hned som si spomenul na duracellkov &lt;a href="http://blog.aspnet.sk/duracellko/archive/2008/04/11/je-naozaj-typ-double-presnej-237-ako-float.aspx" target="_blank"&gt;post&lt;/a&gt; o problemoch datovych typov s pohyblivou desatinnou ciarkou a bol som na spravnej stope. Dufam, ze tento prispevok pomoze niekomu dalsiemu v luskani otazok suvisiacich s peniazmi.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Situacia&lt;/b&gt;&lt;br /&gt;Ste programator znamej online 3D hry &lt;a href="http://secondlife.com/" target="_blank"&gt;2nd Life&lt;/a&gt;. Vasi klienti si mozu do systemu naliat peniaze a potom obchodovat a fungovat ako v realnom svete. Pre jednoduchost predpokladajme, ze tu mame fantasticky slovensky trh a specialne prenho sme vytvorili specialnu x-mas verziu, kde moze klient nahrat peniaze len v SKK mene (EUR este nestihlo prist).&lt;/p&gt;&lt;p&gt;&lt;img src="http://blog.aspnet.sk/blogs/skippo/images/2ndlife.jpg" title="2nd life" alt="2nd life" width="640" height="372" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Vasi klienti mozu virtualne peniaze, ktore vlozili do systemu menit za rozne veci (oblecenie, zetony do kasina, nehnutelnosti a pod.). Idu vianoce a preto budu obchodovat ako divy :-)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Problemy&lt;/b&gt;&lt;br /&gt;Hned na uvod by som rad zdoraznil, ze dane problemy sa nesnazia byt vseobecne pre vsetky typy aplikacie, skor chcu nabadat citatela, aby sa nad nimi zamyslel v kontexte tej &lt;i&gt;jeho&lt;/i&gt; aplikacie.&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Zobrazenie penazi&lt;/b&gt;&lt;br /&gt;Na prvy pohlad jasna vec, no nemusi to tak byt. Na kolko desatinnych miest zobrazime aktualny stav uctu klienta? Pri transakciach penazi tam a spat nam moze stav uctu nadobudnut velmi rozne hodnoty. Kedze pocitac nedokaze niektore cisla s nekonecnym desatinny rozvojom drzat v pamati, pracujeme vzdy s najlepsim priblizenim - aproximaciou. Kolko mieste je OK? V nasej hre by sme pokojne mohli rozhodnut, ze &lt;b&gt;2&lt;/b&gt;. Teda klient po urcitom case hrania a niekolkych trasakciach bude mat na svojom urcte 100,126 SKK. Zobrazime hodnotu na 2 desatinne miesta ale ako - 100,12 alebo 100,13 ?&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. Zaokruhlovanie&lt;/b&gt;&lt;br /&gt;Zaokruhlovanie suvisi aj s bodom c.1 - zobrazenu sumu zaokruhlovat alebo orezavat? Vacsinou chceme byt ku klientom dobri a pri &lt;i&gt;istych &lt;/i&gt;transakciach zaokruhlujeme v prospech klienta. Tu chcem zdoraznit jeden &lt;i&gt;bezpecnostny problem&lt;/i&gt;, ak budeme na klienta prilis dobry, moze sa nam to vypomstit. Predstavme si, ze vojdeme do virtualneho kasina, kupime si za cely nas ucet zetony (nech jeden zeton == 1EUR). Ak zaokruhlujeme aj v tomto pripade v prospech klienta a nechame na strane klienta istu desatinnu cast, moze sa nam lahko stat, ze parta polsko-ruskych nadsencov nam zacne prelievat peniaze tam a spat a za jeden den nas okradne par sto az tisic korun. Obrana pred takymito utokmi vsak patri do ineho clanku.&lt;br /&gt;&lt;/p&gt;&lt;p&gt; Co ale s vypisom jeho stavu uctu. Nuz tu treba byt opatrny. Este raz, nech klient ma na svojom ucte realnych 100,126 SKK a nech padlo rozhodnutie zobrazovat stav na 2 desatinne miesta. Ako - orezat? -zaokruhlit? Nuz obe moznosti sa &lt;i&gt;v nasom&lt;/i&gt; pripade 2nd Life daju aplikovat, s roznymi dosledkami. &lt;/p&gt;&lt;p&gt;Ak &lt;i&gt;orezeme&lt;/i&gt;, klient moze mat pocit, ze mu zobrazujeme nespravne informacie (ludia nie su hlupi), nebodaj, ze sme ho okradli. To moze vazne poskodit nasu rokmi budovanu znacku a znicit cely biznis, ak je klient nespokojny a hlavne nam &lt;b&gt;neveri&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;&lt;i&gt;Zaokruhlime&lt;/i&gt;? V poriadku, klient nemoze namietat, davame mu viac ako od nas ocakava (a ktomu odpovedajuci vtip: &amp;quot;&lt;i&gt;pride chlapik na konkurz na policajta a dostane otazku: kolko je dva plus dva. Muz odpoveda: dvanast. Policajti: vyborne, berieme vas, povedali ste nam viac, ako sme od vas ocakavali&lt;/i&gt;&amp;quot;). Toto rozhodnutie nam vsak moze poriadne skomplikovat zivot, ak na inom mieste v aplikacii ponukame funkcnost typu &amp;#39;&lt;i&gt;zamen vsetky peniaze za zetony&lt;/i&gt;&amp;#39; a uzivatel do textoveho policka napise sumu 100,13 v domienke, ze tolko penazi naozaj ma. Po odklepnuti tlacidka vsak dostane hlasku, ze na svojom ucte nema tolko penazi, a ze si moze zamenit o nieco menej zetonov. To znamena robit dotatocnu kontrolu a rozne cesticky, ktore v konecnom dosledu a pri velkosti hry 2nd Life mozu mat negativny dopad na udrzbu, zmenu a vyvoj aplikacie. Urcite vas hned napada n-dalsich problemov.&lt;/p&gt;&lt;p&gt;&lt;b&gt;3. Implementacia v .NET&lt;/b&gt;&lt;br /&gt;V .NETe a C# mame 3 datove typy pracujuce podla standardu pre aritmetiku s pohyblivou desatinnou ciarkou: double, float, decimal. Ktory typ pouzit. Decimal je urceny na pracu s penaznymi hodnotami a mal by sa na to pouzivat. Je vsak asi 40x pomalsi ako double. Interny popis double a floatu najdete v napr v duracellkovom clanku alebo na wikipedii.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Niekedy situaciu nemame vo svojich rukach a dostaneme pod ruky kod, ktory pracuje s &lt;i&gt;double&lt;/i&gt;. Tiez zdoraznim jednu podstatnu vec, realna hodnota double a jeho textova reprezentacia .ToString() &lt;i&gt;nie su&lt;/i&gt; rovnake. Nie som expert v implementacii aritmetiky s pohyblivou desatinnou ciarkou v .NET, no docital som sa, ze nie je uplna podla standardov. Mozno by sa niekto mohol vyjadrit v komentaroch, aky je momentalny stav v .NET 3.5, teda CLR 2.0 a BCL.&lt;/p&gt;&lt;p&gt;Jeden lahko prehliadnutelny dosledok tohto faktu je, ak pouzivame ASP.NET ViewState. Ak potrebujeme preniest stav-&lt;i&gt;double cislo&lt;/i&gt; vo viewstate, jednoduche priradenie ViewState[&amp;quot;mojeCislo&amp;quot;] = cislo; sposobi (predpokladam) zavolanie overrided .ToString() metody na vstupnom objekte. A v dalsom volani stranky a ziskani hodnoty z viewstate cez double.Parse nam vrati inu hodnotu, ako sme povodne vlozili. Tym padom dostavame neocakavane vysledky v dalsich vypoctoch.&lt;/p&gt;&lt;p&gt;Riesenim je ulozit cislo vo formate &lt;i&gt;round-trip&lt;/i&gt; ViewState[&amp;quot;mojeCislo&amp;quot;] = cislo.ToString(&amp;quot;r&amp;quot;); Ako pise MSDN, takto ziskana reprezentacia cisla zaruci rovnake vysledny po opatovnom parsovani. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Zaver&lt;br /&gt;&lt;/b&gt;Pri praci s aproximaciou realnych cisel je dolezite vediet, ako dana platforma pracuje a implementuje system pre aritmetiku cisel s pohyblivou desatinnou ciarkou. O to viac, ak robime porovnavania a cisla reprezentuju peniaze. Chyby v kode sa opravia lahko, tazko sa opat nadobudne dovera zakaznikov. &lt;/p&gt;&lt;p&gt;Dufam, ze vas mozno trosku odlahceny styl s prikladom z praxe a zaujal. Chcem dodat, ze som sa nesnazil o ziadnu reklamu spominanej hry. Jednoducho mi to padlo ako dobry programatorsko-managersky priklad, pre mnohych z vas mozno nie celkom typickej aplikacie, na ktorych denne pracujete.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Kviz&lt;br /&gt;&lt;/b&gt;Pre naruziveho citatela ponukame v skutku jednoduchu otazku:&amp;nbsp; aka hodnota bude ulozena v booleovskej premennej &lt;b&gt;b&lt;/b&gt; po vykonani nasledujuceho riadku (C#):&lt;br /&gt;&lt;i&gt;bool b = double.NaN == double.NaN&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Tesim sa na Vase odpovede.&lt;br /&gt;&lt;/p&gt;
		&lt;script src="http://connect.facebook.net/en_US/all.js#xfbml=1"&gt;&lt;/script&gt;&lt;fb:like href="" show_faces="true" width="450" font=""&gt;&lt;/fb:like&gt;&lt;img src="http://blog.aspnet.sk/aggbug.aspx?PostID=55429" width="1" height="1"&gt;</description><category domain="http://blog.aspnet.sk/skippo/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/double/default.aspx">double</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/float/default.aspx">float</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/2nd+Life/default.aspx">2nd Life</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/.NET/default.aspx">.NET</category></item><item><title>FUN: Life Management (Best Practices serie)</title><link>http://blog.aspnet.sk/skippo/archive/2007/06/29/fun-life-management-best-practices-serie.aspx</link><pubDate>Fri, 29 Jun 2007 07:26:00 GMT</pubDate><guid isPermaLink="false">cbdfeddd-8b45-43cb-b10b-361e40cba84b:112</guid><dc:creator>skippo</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.aspnet.sk/skippo/rsscomments.aspx?PostID=112</wfw:commentRss><comments>http://blog.aspnet.sk/skippo/archive/2007/06/29/fun-life-management-best-practices-serie.aspx#comments</comments><description>&lt;p&gt;
Život programátora nie je prechádzka ružovou záhradou a bez poriadnej organizácie pracovného času sa vynikajúce výsledky dosahujú pomerne ťažko. V tomto diely sa pozrieme na dôležitú časť &lt;i&gt;Life&lt;/i&gt; Management-u, konkrétne &lt;i&gt;Day&lt;/i&gt; Management programátora.
&lt;/p&gt;
&lt;p&gt;
Typickou črtou programátorov je snaha vytvárať kód, ktorý bude znovu-použiteľný. Ako .NET programátori spomeňme napríklad riešenie založené na User Control, ktoré pri dobrom návrhu môže poslúžiť nie len autorovi. Najnovšie štúdie vedcov z Matematicko-Fyzikálnej fakulty prinášajú zaujímavé výsledky. Po niekoľko ročnom výskume vedci dokázali transformovať optimalizácie použiteľné pri tvorbe zdrojových kódov na ľudí. Dokázali odstrániť všetky úzke miesta (bottleneck) dňa programátora a vytvorili model, ktorý bude zrejme znamenať zmenu v živote mnohých z nás. Nech sa páči:
&lt;/p&gt;
&lt;img src="http://blog.aspnet.sk/blogs/skippo/images/modern_life_smaller.jpg" alt="" /&gt;
&lt;p&gt;
Na prvý pohľad niektoré veci nemusia byť každému viditeľné, jedná sa totiž o optimalizáciu najvyššej úrovne, slangovo nazývanou aj &lt;i&gt;master coder&lt;/i&gt; alebo &lt;i&gt;alone in the dark&lt;/i&gt;. Podobné chovanie sme boli schopní v prírode pozorovať na špecifických jedincoch, tzv. &lt;i&gt;gejmerov&lt;/i&gt;, avšak ich správanie je &lt;i&gt;jednoduchšie&lt;/i&gt; a vytvorenie všeobecného modelu pre programátorov sa doposiaľ nikomu nepodarilo. 
&lt;/p&gt;
&lt;p&gt;
Vedci sa momentálne snažia o customizáciu modelu, ich snahou je nahradiť prostredné časti modelu. Nové časti modelu majú zatiaľ kódové označenie &lt;i&gt;vodka&lt;/i&gt; a &lt;i&gt;drink&lt;/i&gt;. Všetky informácie sú označené ako &lt;i&gt;confidential&lt;/i&gt;, vedci zatiaľ neposkytujú žiadne nové prehlásenia. Experimenty a testy podľa našich informácii dopadli veľmi dobre. Tak im držme palce.
&lt;/p&gt;
&lt;p&gt;
Prajem pekný deň a teším sa nabudúce pri ďalšom pokračovaní.
&lt;/p&gt;
&lt;/p&gt;

&lt;/p&gt;
		&lt;script src="http://connect.facebook.net/en_US/all.js#xfbml=1"&gt;&lt;/script&gt;&lt;fb:like href="" show_faces="true" width="450" font=""&gt;&lt;/fb:like&gt;&lt;img src="http://blog.aspnet.sk/aggbug.aspx?PostID=112" width="1" height="1"&gt;</description><category domain="http://blog.aspnet.sk/skippo/archive/tags/Fun/default.aspx">Fun</category></item><item><title>Indikátor AJAX volaní na pozadí</title><link>http://blog.aspnet.sk/skippo/archive/2007/06/21/indik-225-tor-ajax-requestu.aspx</link><pubDate>Thu, 21 Jun 2007 14:45:00 GMT</pubDate><guid isPermaLink="false">cbdfeddd-8b45-43cb-b10b-361e40cba84b:77</guid><dc:creator>skippo</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.aspnet.sk/skippo/rsscomments.aspx?PostID=77</wfw:commentRss><comments>http://blog.aspnet.sk/skippo/archive/2007/06/21/indik-225-tor-ajax-requestu.aspx#comments</comments><description>&lt;p&gt;
Pri browsení na internete som narazil na jeden veľmi pekne urobený generátor animovaných GIF-ov -&lt;br /&gt;&lt;a href="http://www.ajaxload.info/" target="_blank"&gt;http://www.ajaxload.info/&lt;/a&gt;. Môže byť nápomocný všetkým, ktorí pracujú v AJAX-e a potrebuju používateľa aplikácie informovať o asynchrónnom volaní na pozadí, tzv. &lt;i&gt;callback&lt;/i&gt;. Design stránky je jednoduchý a krásny zároveň.
&lt;/p&gt;
&lt;div&gt;
&lt;img src="http://blog.aspnet.sk/blogs/skippo/images/progressbar.gif" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;b&gt;Použitie&lt;/b&gt;&lt;br /&gt;
Stačí si zvoliť typ animácie (možeme si vybrať z viac ako 35tich animácii), farbu popredia a pozadia (ide zvoliť aj priehľadné) a po odkliknutí tlačidla &amp;quot;Generate It&amp;quot; sa animovaný GIF zobrazí v &lt;i&gt;preview&lt;/i&gt; oblasti. K dispozícii je aj TOP10 najobľúbenejších animácii, ktoré vytvorili používatelia z celého sveta.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Ďalšie zbierky&lt;/b&gt;&lt;br /&gt;
Okrem tohto generátora existujú aj ďalšie zbierky animácii. bežte sa pozrieť ešte &lt;a href="http://mentalized.net/activity-indicators/" target="_blank"&gt;tu&lt;/a&gt; a &lt;a href="http://www.napyfab.com/ajax-indicators/" target="_blank"&gt;tu&lt;/a&gt;. Prvá zbierka obsahuje sériu animácii od rôznych autorov, licencované su pod Public Domain, t.j. môže ich použiť kto chce, na čo chce. V prvom, aj druhom prípade je možnosť voľby pozadia (biela, čierna), pričom prvá zbierka umožňuje nastaviť ľubovoľnú farbu.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;GMail AJAX notifikácia&lt;/b&gt;&lt;br /&gt;
Ak sa Vám páči notifikácia AJAX callback-ov ako majú Google vo svojom GMail a nie ste zdatní v CSS, potom sa mrknite &lt;a href="http://codeclimber.net.nz/archive/2007/05/17/How-to-make-a-Gmail-like-loading-indicator-with-ASP.NET-Ajax.aspx" target="_blank"&gt;sem&lt;/a&gt;. Autor na svojej stránke popisuje ako umiestniť animáciu do pravého-horného rohu obrazovky, plus nejaký malý pokec o ASP.NET AJAX UpdateProgress &lt;i&gt;kontrolke&lt;/i&gt;. Ako to všetko rozbehať v našom dobrom priateľovi IE6 nájdete &lt;a href="http://weblogs.asp.net/lduveau/archive/2007/05/25/ajax-loading-indicator-like-gmail.aspx" target="_blank"&gt;tu.&lt;/a&gt;
&lt;/p&gt;
		&lt;script src="http://connect.facebook.net/en_US/all.js#xfbml=1"&gt;&lt;/script&gt;&lt;fb:like href="" show_faces="true" width="450" font=""&gt;&lt;/fb:like&gt;&lt;img src="http://blog.aspnet.sk/aggbug.aspx?PostID=77" width="1" height="1"&gt;</description><category domain="http://blog.aspnet.sk/skippo/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/CSS/default.aspx">CSS</category></item><item><title>FUN: Lunch Management (Best Practices serie)</title><link>http://blog.aspnet.sk/skippo/archive/2007/06/21/fun-lunch-management-best-practices-series.aspx</link><pubDate>Thu, 21 Jun 2007 06:53:00 GMT</pubDate><guid isPermaLink="false">cbdfeddd-8b45-43cb-b10b-361e40cba84b:71</guid><dc:creator>skippo</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.aspnet.sk/skippo/rsscomments.aspx?PostID=71</wfw:commentRss><comments>http://blog.aspnet.sk/skippo/archive/2007/06/21/fun-lunch-management-best-practices-series.aspx#comments</comments><description>&lt;p&gt;
Poznáme to všetci, pár minút pred dvanástou, brucho programátora vyhráva ako nový iPod... je čas obeda. Človek je ale tvor spoločenský a nerád chodí do spoločnosti osamote, preto si v tomto článku predstavíme najnovšie postupy ako zmenežovať dobrý obed.
&lt;/p&gt;
&lt;p&gt;
Chlapci z &lt;a href="http://msdn2.microsoft.com" target="_blank"&gt;MSDN&lt;/a&gt; zatiaľ nemali čas apdejtnuť túto každodennú &lt;i&gt;critical&lt;/i&gt; tému do sekcie &lt;i&gt;best practices&lt;/i&gt;, preto je tento blog poctený uviesť ju ako prvý.
&lt;/p&gt;
&lt;div&gt;
&lt;img src="http://blog.aspnet.sk/blogs/skippo/images/obed.jpg" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;
Uf, a máme to za sebou.
&lt;/p&gt;
&lt;p&gt;
V článku sme sa zaoberali lunch managementom, predstavili sme si best practice s názorným príkladom a detailným výkladom. Praktické prevedenie je naplánované na dnes, 12:00 SEC. Veľa zdaru.
&lt;/p&gt;
&lt;p&gt;
A teraz trošku seriózne :-) Tento obrázok ma veľmi pobavil (poslal mi ho kolega, originál autorom je &lt;a href="http://www-ucjf.troja.mff.cuni.cz/scheirich/index.php?s=4&amp;amp;strip=51"&gt;Daniel Scheirich&lt;/a&gt;), pretože takto presne to vyzerá u nas vo firme cca o 11:30 päť dní v týždni. Teraz sa priznajte, kto ste na tom rovnako (zle) :-)
&lt;/p&gt;
		&lt;script src="http://connect.facebook.net/en_US/all.js#xfbml=1"&gt;&lt;/script&gt;&lt;fb:like href="" show_faces="true" width="450" font=""&gt;&lt;/fb:like&gt;&lt;img src="http://blog.aspnet.sk/aggbug.aspx?PostID=71" width="1" height="1"&gt;</description><category domain="http://blog.aspnet.sk/skippo/archive/tags/Fun/default.aspx">Fun</category></item><item><title>Singletony, HttpContext a ThreadStatic alebo čo je v skutočnosti private-local v ASP.NET</title><link>http://blog.aspnet.sk/skippo/archive/2007/06/15/singletony-httpcontext-a-threadstatic-alebo-o-je-v-skuto-nosti-private-local-v-asp-net.aspx</link><pubDate>Fri, 15 Jun 2007 06:56:00 GMT</pubDate><guid isPermaLink="false">cbdfeddd-8b45-43cb-b10b-361e40cba84b:25</guid><dc:creator>skippo</dc:creator><slash:comments>203</slash:comments><description>&lt;p&gt;Ahoj všetci. Nakoľko je toto môj prvý post na tomto blogu, rád by som na úvod napísal pár vecí o mne a o tom, čomu sa chcem venovať. Programujem už nejaký ten rôčik, mal som tú česť pracovať na širokej škále projektov, od windows a web aplikácii, cez skriptovacie jazyky, až po komplikovanejšie paralelné aplikácie na Linuxovom klastri. S ASP.NET robím pomerne krátko, takže moje príspevky profíkom zrejme veľa nedajú, no ďalšie generácie slovenských, a možno aj českých programátorov, tu možno objavia stratégiu bojov, ktoré sme zvádzali snáď všetci. A v neposledom rade možno svojou troškou podporím slovenskú a českú .NET komunitu. Myslím, že som konečne objavil oblasť (.NET, webové aplikácie), ktorej sa chcem dlhodobo venovať. V práci sa venujem prevažne užívateľskej strane projektov, moje príspevky sa budú týkať oblastí ako Ajax, JavaScript, CSS, ASP.NET a bezpečnosť. Opakujem prevažne. :-) V rámci toho mála voľného času sa zaoberám grafikou a tvorbou oldschool hier. Ak má niekto podobné hobby, ozvite sa, rád si pokecám a vymením skúsenosti. A teraz späť k téme. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Singleton_pattern" target="_blank"&gt;Singleton&lt;/a&gt; je už klasik medzi návrhovými vzormi (design patterns). Jednoducho povedané, termín singleton reprezentuje triedu, ktorá umožní vytvoriť práve a iba jednu jej inštanciu. Zvyčajne k jej metódam a vlastnostiam pristupujeme veľmi jednoducho, a to cez statickú vlastnosť (property), ktorá vráti inštanciu triedy, ak je vytvorená. V opačnom prípade ju vytvorí a vráti inštanciu. Spomínaná vlastnosť garantuje maximálne jednú inštanciu triedy. Načo je nám taký singleton dobrý? V prvom rade umožňuje tzv. &lt;a href="http://www.devx.com/tips/Tip/13436" target="_blank"&gt;lazy instantiation&lt;/a&gt;, čo voľne preložené znamená, že inštancia triedy sa vytvorí až v momente, ked budeme k triede pristupovať (ak vôbec). Ďalej oproti static metódam a properties je singleton trieda thread-safe, t.j. volanie metód sa nám nezgulášuje. Tu nie som celkom presný, singleton môže byť implementovaný ako not-thread-safe, takejto implementácii by sme sa mali &lt;a href="http://www.yoda.arachsys.com/csharp/singleton.html" target="_blank"&gt;vyhnúť&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Príklad je lepší ako sto slov, preto ukážka jednoduchého thread-safe singletonu:&lt;/p&gt;
&lt;div style="WIDTH:520px;OVERFLOW:auto;"&gt;&lt;pre&gt;public class MojSingleton
{
    private static MojSingleton m_oInstance=null;
    private static readonly object padlock = new object();

    private MojSingleton ()
    {
    }

    public static MojSingleton oInstance
    {
        get
        {
            lock (padlock)
            {
                if (m_oInstance==null)
                {
                    m_oInstance = new MojSingleton();
                }
                return m_oInstance;
            }
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pre tých, ktorí budú ohŕňať nos nad zamykaním obsahu gettera, napíšem len to, že je to rovnaký problém ako klasická snaha programátorov o optimalizáciu použitia premenných alebo volania funkcie, ktorá je v dobe dnešných kompilátorov zanedbateľná. Toto v 99% nie je úzke miesto programu (bottleneck) a osobne by som sa pozrel na volanie databáz, ajax callbackov resp. dynamickú úpravu obsahu napríklad javascriptom. &lt;/p&gt;
&lt;p&gt;Takáto implementácia je fajn, ale čo v prípade ASP.Net, kde nám každý request obsluhuje jeden z niekoľkých threadov poolu a my nechceme zdieľať pre všetky requesty jeden singleton? Šikovný pán Roman Macháček ponúka &lt;a href="http://www.objects.cz/clanky/clanek13/clanek13.asp" target="_blank"&gt;modifikované riešenie&lt;/a&gt;: &lt;/p&gt;
&lt;div style="WIDTH:520px;OVERFLOW:auto;"&gt;&lt;pre&gt;public class Singleton
{
    private Singleton()  {}

    public static Singleton Instance
    {
        get 
        {
            if (HttpContext.Current.Session[&amp;quot;Singleton&amp;quot;]==null)
                HttpContext.Current.Session[&amp;quot;Singleton&amp;quot;]=new Singleton();
            return (Singleton)HttpContext.Current.Session[&amp;quot;Singleton&amp;quot;];
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Niektoré moje singletony zgrupujú iba metódy a volanie konštruktora je zanedbateľné, preto sa mi ukladanie singletonu do objektu Session velmi nepozdávala. V prípade, že by som v triede ukladal nejaké privátne dáta a potreboval ich držať pre daný request počas celej session, hore uvedená implementácia by mi úplne vyhovovala. Avšak ako každý programátor, v túžbe optimalizovať moju aplikáciu som začal hľadať riešenie, ako vytvárať singleton na úrovni requestu. T.j. po zavolaní &lt;span style="FONT-FAMILY:Courier New;"&gt;Request_End&lt;/span&gt; funkcie by sa singleton pekne a čisto odpratal. Pokiaľ možno automaticky. Pri svojom pátraní som sa dostal k parametru &lt;span style="FONT-FAMILY:Courier New;"&gt;[ThreadStatic]&lt;/span&gt;. Aplikácia tohto parametra na static field spôsobí, že thready si nebudú field zdieľať, ale každý thread bude mať svojú vlastnú inštanciu threadu. (Poznámka na okraj: ako by ste do slovenčiny preložili termín &lt;i&gt;field&lt;/i&gt;?). Vyzerá to dobre, stačí ak modifikujeme prvý príklad singletonu a sme za vodou. Teraz sa priznám, že som to neskúšal a neviem povedať, aké situácie by bolo treba riešiť. Uvádzam preto ešte jeden príklad singletonu, ktorý je thread-safe, ale bez uzamykania. Túto verziu budú preferovať odporcovia príkazu lock :-) A ostatní, ktorí sa s touto implementáciou ešte nestretli, sa niečo nové dozvedia. Pokial volanie konštruktora nie je časovo náročné a nespôsobí nejaké vedľajšie účinky, vo veľa prípadoch si vystačíte nie celkom lazy singletonom: &lt;/p&gt;
&lt;div style="WIDTH:520px;OVERFLOW:auto;"&gt;&lt;pre&gt;public class MojSingleton
{
    [ThreadStatic] 
    private static readonly MojSingleton m_oInstance=new MojSingleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    private static MojSingleton()
    {
    }

    private MojSingleton()
    {
    }

    public static MojSingleton oInstance
    {
        get
        {
            return m_oInstance;
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY:Courier New;"&gt;[ThreadStatic]&lt;/span&gt; je fajn, ale nefunguje tak, ako by ste na prvý pohľad očakávali. Dá sa použiť iba v niektorých situáciach. Vysvetlím. Keď som sa dozvedel o tomto attribúte, už od začiatku ma sprevádzala akási nedôvera. Static fieldom veľmi neverím, preto aj tie pochybnosti ohľadom už toľkokrát spomínaného atribútu. Skúmal som teda ďalej, aké sú reálne možnosti jeho použitia. &lt;/p&gt;
&lt;p&gt;“Aj ked si myslíš, že vieš čo robíš, NIE je bezpečné ukladať čokoľvek v ThreadStatic fielde, CallContext-te alebo Thread Local Storage v prípade ASP.NET aplikácie, ak je nejaká šanca, že hodnota bude nastavená pred volaním &lt;span style="FONT-FAMILY:Courier New;"&gt;Page_Load&lt;/span&gt; (napríklad v &lt;span style="FONT-FAMILY:Courier New;"&gt;IHttpModule&lt;/span&gt; alebo konštruktore stránky) a pristupovať sa k nej bude počas nej alebo neskôr” &lt;a href="http://piers7.blogspot.com/2005/11/threadstatic-callcontext-and_02.html" target="_blank"&gt;Piers7&lt;/a&gt;. 
&lt;p&gt;Piers vo svojom blogu dobre rozanalyzoval otázky okolo spracovania requestu ASP.Net-tom. Problém s ThreadStatic atribútom spočíva v tom, že ASP.NET nie je iba &lt;i&gt;thread-pooled&lt;/i&gt; ale aj &lt;i&gt;thread agile&lt;/i&gt; (-: Opäť otázka pre náruživého čitateľa: Ako preložiť posledné slovné spojenie do rodnej materčiny? :-) Zjednodušene povedané, ASP.NET každému requestu pridelí nejaký thread z poolu. Tých treadov je tam štandardne cca 25 (?). Tu je kameň úrazu, pretože neplatí tvrdenie: request je obsluhovaný threadom od jeho začiatku do konca. To anglické thread agile znamená, že ASP.NET môže (a robí) prepnúť thready počas spracovávania requestu a dokáže obslúžiť viac requestov jedným threadom. A teda jeden request može byť spracovaný viacerými threadmi. Nemáme kontrolu nad Thread Pool a životným cyklom threadov, preto atribút &lt;span style="FONT-FAMILY:Courier New;"&gt;[ThreadStatic]&lt;/span&gt; nefunguje ako privátny a lokálny v rámci requestu, ale ako privátny a lokálny medzi všetkými threadmi poolu. Ak vieme kontrolovať thready, potom aj správanie atribútu je korektné, to ale neplatí pre ASP.NET. 
&lt;p&gt;Pri vysokej záťaži ASP.NET a rôznej časovej náročnosti spracovávaných funkcií sa môže stať, že príliš veľa I/O threadov spracováva requesty. ASP.NET potom zastaví spracovávanie requestu, odloží ho niekam do fronty, a príslušný thread bude pracovať na ďalšom requeste. Časom je request opať na rade a priradí sa mu nejaký dostupný worker thread. (poznámka: do hĺbky spracovania requestov I/O threadmi nevidím, možno by niekto v diskusii mohol ozrejmiť a lepšie konkretizovať túto časť a spojenie I/O threadov a worker threadov). &lt;/p&gt;
&lt;p&gt;Ale späť k téme. Pri migrovaní requestu medzi threadmi nepremigruje všetko, ako by si niekto mohol myslieť, ale iba &lt;span style="FONT-FAMILY:Courier New;"&gt;HttpContext&lt;/span&gt;. Dáta uložené napríklad v &lt;span style="FONT-FAMILY:Courier New;"&gt;CallContext&lt;/span&gt; sú fuč. Keď už je nám známe migrovanie threadov, pri použití &lt;span style="FONT-FAMILY:Courier New;"&gt;[ThreadStatic]&lt;/span&gt; nastáva jeden základný problém: ThreadStatic fieldy sú privátne a lokálne zdieľané medzi threadmi (t.j. vždy iba jeden z threadov pristupuje k dátam). Pri migrovaní sa môže ľahko stať, že iný thread dostane dáta niekoho iného. Riešením je použitie niečoho, čo je naozaj privátne a lokálne, ale vzhľadom na request. Odpoveď už zaznela - je to &lt;span style="FONT-FAMILY:Courier New;"&gt;HttpContext&lt;/span&gt;. &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspnet/html/asp01242002.asp" target="_blank"&gt;Kontext&lt;/a&gt; migruje medzi threadmi aj so všetkými dátami. 
&lt;p&gt;Veľmi pekným a odporúčaným &lt;a href="http://www.hanselman.com/blog/ATaleOfTwoTechniquesTheThreadStaticAttributeAndSystemWebHttpContextCurrentItems.aspx" target="_blank"&gt;miestom pre ukladanie dát&lt;/a&gt; v rámci jedného HTTP requestu je &lt;span style="FONT-FAMILY:Courier New;"&gt;HttpContext.Current.Items&lt;/span&gt;. Tento objekt implementuje interfejs &lt;span style="FONT-FAMILY:Courier New;"&gt;IDictionary&lt;/span&gt;, a teda ponúka elegantný prístup k dátam vo forme kľúč – hodnota. Pekné miesto na uloženie singletonov. A poďme rovno na príklad, jemne modifikovaný singleton č.2: &lt;/p&gt;
&lt;div style="WIDTH:520px;OVERFLOW:auto;"&gt;&lt;pre&gt;public class MojSingleton
{
      private MojSingleton ()
      {
      }

      private static readonly object padlock = new object();

      private static readonly string CONTEXT_ITEMS_KEY = &amp;quot;__MojSingleton&amp;quot;;

      public static MojSingleton oInstance
      {
          get
          {
              lock (padlock)
              {
                  if (HttpContext.Current.Items[CONTEXT_ITEMS_KEY] == null)
                      HttpContext.Current.Items[CONTEXT_ITEMS_KEY] = new MojSingleton ();
                  return (MojSingleton)HttpContext.Current.Items[CONTEXT_ITEMS_KEY];
              }
          }
      }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Výhody a nevýhody. Singleton je naozaj thread-safe, dáta prežijú počas celého requestu a po ukončení je inštancia pekne odprataná z pamäte -- automaticky. Ostatné controly môžu využívať funkcie a dáta inštancie triedy a inštancia sa vytvára až vtedy, ak je potrebná. Ak potrebujete uložiť dáta medzi requestami, použite objekt Session, vid. príklad č.2. Alebo ak volanie konštruktora je drahé a uložené miesto v Session naopak. Nevýhodou je, že nižšie vrstvy vašej aplikácie musia referencovat namespace System.Web, aby mohli pristupovať k property &lt;span style="FONT-FAMILY:Courier New;"&gt;HttpContext.Current&lt;/span&gt;. V prípade väčších a zložitejších aplikácií to nemusí byť dobré a žiadúce, ak napríklad plánujete neskôr použiť spodné vrstvy aplikácie pre winforms alebo console projekty. Veľa programátorov potom pristupuje priamo k threadu a ukladá dáta na nejaké storage miesto spojené s threadom, v snahe vyhnúť sa úzkej napojenosti na webové prostredie. Tento prístup však nebude fungovat v prípade ASP.NET, veriť možno iba HttpContext-tu.&lt;/p&gt;
&lt;p&gt;A čo s &lt;span style="FONT-FAMILY:Courier New;"&gt;[ThreadStatic]&lt;/span&gt; ? Nie je to nepoužiteľný atribút, avšak v ASP.NET aplikáciach by sa mal používať opatrne. Nezabudnúť, že request može byť spracovaný rôznymi threadmi počas svojho krátkeho života. Preto ukladanie dát v takomto fielde je zlým riešením. Ak však trieda, singleton, obsahuje iba metódy a žiaden stav (dáta), bude jeho použitie bezproblémové. (-: až do chvíle, keď zabudneme na ThreadStatic a pridáme do triedy nejaké data :-)&lt;/p&gt;
&lt;p&gt;Uvítam, ak do diskusie prispejete aj svojimi poznatkami, prípadne dodatočným vysvetlením. Ak na niektorom mieste píšem nesprávne, napíšte mi a text opravím, resp. doplním. Vďaka a do threadovania. &lt;/p&gt;
&lt;p&gt;Update: tento (jediný) príspevok som uverejnil na svojom predchádzajúcom &lt;a href="http://www.dotnetgroup.sk/blogs/skippo/" target="_blank"&gt;blogu&lt;/a&gt;, no nakoľko je server už dlhú dobu mimo provoz, rozhodol som sa presunúť na tento portál, kde už nejaký ten čas pôsobím (pozdravujem fórum). Dúfam, že to tu vydrží dlhšie :-) &lt;/p&gt;
		&lt;script src="http://connect.facebook.net/en_US/all.js#xfbml=1"&gt;&lt;/script&gt;&lt;fb:like href="" show_faces="true" width="450" font=""&gt;&lt;/fb:like&gt;&lt;img src="http://blog.aspnet.sk/aggbug.aspx?PostID=25" width="1" height="1"&gt;</description><category domain="http://blog.aspnet.sk/skippo/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/Design+Patterns/default.aspx">Design Patterns</category><category domain="http://blog.aspnet.sk/skippo/archive/tags/Thread/default.aspx">Thread</category></item></channel></rss>