Blocking read kiváltása mivel?

July 2nd, 2010

Tegyük fel írok egy tcp kliens programot, TcpClient, NetworkStream és társaival. A NetworkStream.Read blokkoló módon működik. Nekem az kell, hogy bármikor tudjam abortálni a tcp csatornát. A Read ha miatta beragad az egy szál, az Thread.Abort állítja le (igaz, az Thread.Interruptot még nem próbáltam).

Lehetséges megoldásként az async BeginReadet javasolják, de azzal meg az a bajom, hogy minden kis darab olvasása után egy waithandlere kell várni, ami meg context switchet eredményez, így a nagysebességű időszakokban belassít.
Mi vajon a korrekt megoldás, ami megszakítható és gyors is?

Access to modified closure figyelmeztetés a Resharperben

June 24th, 2010

Már ez önmagában megéri a termék árát, máskülönben sok órát lehet debugolni a probléma miatt.

Alább a langId változó bevezetését javasolta, okkal, másképp a variable capturing beszopat. De csúnyán.


foreach (var lang in languages)
{
    var langId = lang.Value.ID;
    resStringLookup[lang.Key] = new CachedEntityLookup<ResString, int, string>(
        rs => rs.ResStringIntID, //Kulcs a resid
        rs => rs.TransText,     //A tartalom a lokalizált szöveg
        rs => rs.LanguageID == langId);  //Ehhez a nyelvhez építjük fel a táblát
}

Tőzsde: Analysis of the “Flash Crash” Date of Event: May 6, 2010

June 23rd, 2010

Informatikai elemzés, mitől volt a tőzsdebeszakadás.
Egészen megdöbbentő. Kb. arról szól, hogy a New Yorki tőzsdéről elkezdtek késni az adatok, amitől megborult a tőzsdék közötti, legjobb árat szabályozó replikációs rendszer. A késés oka az lehetett, hogy túlterhelődött a tőzsde adatelosztója, és az ajánlatok időbélyegét (elég furcsa módon) nem az ajánlat beadásakor írják be, hanem amikor kijön a csőből. Emiatt kívülről nem látszik a csúszás. De ami érdekesebb, mitől dugult be a tőzsde?
Ma már nagyon sok nagyfrekvenciás algoritmus fut, amelyek már ms alatti idők alatt döntenek és reagálnak (ezek a szerverek a tőzsde LAN-ján vannak, nagyon közel a fő számítógépek hálózatához, így a hálózati késeltetés csak mikrosec nagyságrendű).
Ezek egymással persze versenyeznek. És itt jön a buli. Valamelyik algoritmus elkezd mpeknként több ezer ajánlatot beküldeni. Ő persze nem elemzi ezeket, hisz ő küldte be. De a többiek ezt elemzik, és amíg ezzel töltik az időt, ő ráér kisajtolni a profitot. Spamelik a tőzsdét. Ez persze destabilizálja az egész rendszert. A skynet ébredezik.

Best Practices: How to implement INotifyPropertyChanged right?

June 17th, 2010

Jó összefoglaló a témában.

Update: ez lett a vége:


using System.ComponentModel;
using System.Threading;
using Krs.Ats.IBNet;

namespace ATS.IB
{
    /// <summary>
    /// Real-time data descriptor for IB tick data
    /// </summary>
    public class MarketData : INotifyPropertyChanged
    {
        public Contract IBContract { get; set; }
        public Ticker Ticker { get; set; }

        private decimal lastPrice;
        public decimal LastPrice
        {
            get { return lastPrice; }
            set
            {
                lastPrice = value;
                OnPropertyChanged(LastPriceChangedArgs);
            }
        }

        private decimal lastBid;
        public decimal LastBid
        {
            get { return lastBid; }
            set
            {
                lastBid = value;
                OnPropertyChanged(LastBidChangedArgs);
            }
        }

        private decimal lastAsk;
        public decimal LastAsk
        {
            get { return lastAsk; }
            set
            {
                lastAsk = value;
                OnPropertyChanged(LastAskChangedArgs);
            }
        }

        private int lastSize;
        public int LastSize
        {
            get { return lastSize; }
            set
            {
                lastSize = value;
                OnPropertyChanged(LastSizeChangedArgs);
            }
        }

        private int lastAskSize;
        public int LastAskSize
        {
            get { return lastAskSize; }
            set
            {
                lastAskSize = value;
                OnPropertyChanged(LastAskSizeChangedArgs);
            }
        }

        private int lastBidSize;
        public int LastBidSize
        {
            get { return lastBidSize; }
            set
            {
                lastBidSize = value;
                OnPropertyChanged(LastBisSizeChangedArgs);
            }
        }

        private static readonly PropertyChangedEventArgs LastPriceChangedArgs = ObservableHelper.CreateArgs<MarketData>(x => x.LastPrice);
        private static readonly PropertyChangedEventArgs LastBidChangedArgs = ObservableHelper.CreateArgs<MarketData>(x => x.LastBid);
        private static readonly PropertyChangedEventArgs LastAskChangedArgs = ObservableHelper.CreateArgs<MarketData>(x => x.LastAsk);
        private static readonly PropertyChangedEventArgs LastSizeChangedArgs = ObservableHelper.CreateArgs<MarketData>(x => x.LastSize);
        private static readonly PropertyChangedEventArgs LastBisSizeChangedArgs = ObservableHelper.CreateArgs<MarketData>(x => x.LastBidSize);
        private static readonly PropertyChangedEventArgs LastAskSizeChangedArgs = ObservableHelper.CreateArgs<MarketData>(x => x.LastAskSize);

        private void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            var eventHandler = PropertyChanged;
            if (eventHandler != null)
            {
                if (guiSyncContext != SynchronizationContext.Current)
                {
                    guiSyncContext.CallOnMainThread(OnPropertyChanged, e);
                }
                else
                {
                    eventHandler(this, e);
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private SynchronizationContext guiSyncContext = SynchronizationContext.Current;

        public void SetGuiSyncContext()
        {
            guiSyncContext = SynchronizationContext.Current;
        }
    }
}

Elkúrtuk, nem kicsit, nagyon

June 7th, 2010

Kósa shortol:

Bmeg, ezeknek szerintem elment az esze. Vagy tényleg shortolnak. Nem tudom, melyik a veszélyesebb.
Ami leginkább felháborít a dologban, az az, hogy nem vállalják a felelősséget a szavaikért. Á, miattunk nem esik a tőzsde. Persze, hogy most az egész világban idegesek a befektetők, morog a maci, de pont ilyenkor kell ésszel beszélni.
Mint a kisgyerek, amikor tűzzel játszik, leég a ház, aztán néz kerek szemekkel, hogy ő nem így gondolta. De ez egy ország, nem egy ház!

Visual Studio unit teszt profilozás

May 17th, 2010

A unit tesztek kiváló sebességmérési célok lehetnek, mivel kimagozottan futtatnak egy adott kódrészletet. A unit teszten jobb gomb, create performace session. Zseniális, csak nem megy, ha 64 bitesre van állítva a unit teszt host. Nem láttam ledokumentálva (vagy csak nálam nem megy ez).
Egyszerűen soha nem ér véget a tesztelés, beragad a profiler session.

Dynamic sebesség újra

May 17th, 2010

Hogy ne a levegőbe beszéljek:


using System;
using System.Diagnostics;
using System.Reflection;

namespace DynamicTypeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            object target = "alma";
            object arg = "m";

            string a2 = (string)arg;

            Stopwatch w = Stopwatch.StartNew();

            const int callNumber = 1000 * 1000;
            for (int i = 0; i < callNumber; i++)
            {
                Type[] argTypes = new Type[] { typeof(string) };
                MethodInfo mi = target.GetType().GetMethod("Contains", argTypes);
                object[] oa = new object[] { a2 };
                bool b = (bool)mi.Invoke(target, oa);
            }

            w.Stop();
            Console.WriteLine("Reflection hívási idő: {0}", w.Elapsed);
            double elapsedTickForReflection = w.ElapsedTicks;

            w.Restart();

            for (int i = 0; i < callNumber; i++)
            {
                bool b = ((dynamic)target).Contains(a2);
            }

            w.Stop();
            Console.WriteLine("Dynamic hívási idő: {0}", w.Elapsed);

            Console.WriteLine("A dynamic {0}x gyorsabb volt.", elapsedTickForReflection / w.ElapsedTicks);
        }
    }
}

Reflection hívási idő: 00:00:02.5393161
Dynamic hívási idő: 00:00:00.2049100
A dynamic 12.3923444658829x gyorsabb volt.

Ha ügyesebbek vagyunk, és kivesszük a ciklusból a reflection előkészítését:


using System;
using System.Diagnostics;
using System.Reflection;

namespace DynamicTypeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            object target = "alma";
            object arg = "m";

            string a2 = (string)arg;

            Stopwatch w = Stopwatch.StartNew();

            Type[] argTypes = new Type[] { typeof(string) };
            MethodInfo mi = target.GetType().GetMethod("Contains", argTypes);
            object[] oa = new object[] { a2 };

            const int callNumber = 1000 * 1000;
            for (int i = 0; i < callNumber; i++)
            {
                bool b = (bool)mi.Invoke(target, oa);
            }

            w.Stop();
            Console.WriteLine("Reflection hívási idő: {0}", w.Elapsed);
            double elapsedTickForReflection = w.ElapsedTicks;

            w.Restart();

            for (int i = 0; i < callNumber; i++)
            {
                bool b = ((dynamic)target).Contains(a2);
            }

            w.Stop();
            Console.WriteLine("Dynamic hívási idő: {0}", w.Elapsed);

            Console.WriteLine("A dynamic {0}x gyorsabb volt.", elapsedTickForReflection / w.ElapsedTicks);
        }
    }
}

Reflection hívási idő: 00:00:01.2058747
Dynamic hívási idő: 00:00:00.2044023
A dynamic 5.89951388765798x gyorsabb volt.

Jó ez, szeretjük, pedig nem is COMolunk.

Miért szeretem a dynamic típust reflection helyett?

May 17th, 2010

Ezért:


var allEntities = (IEnumerable)reposType.GetMethod("GetAll", new Type[] { typeof(string[]) }).Invoke(repos, new object[] { includes });

vs.


var allEntities = (IEnumerable)repos.GetAll(includes);

Emellett a dynamic vagy 10x gyorsabb, még akkor is, ha a reflectionnél cachelem a típusleírókat.

Mi hiányzik a Visual Studioból Resharper nélkül?

May 17th, 2010

Pár napja nem megy a Resharprem, azóta olyan dolgozni a VS-val, mintha notepad előtt ülnék. Fel nem tudom sorolni azt a sok dolgot, amivel segít kódírás közben, pár dolog csak mintaképp:
Refactoring:
Inline, Pull members up és down, Safe delete, Convert Property to Method és vissza, related itemek átnevezése is, make local variable, field vagy parameter (ezeket nagyon sokat használtam), change signature.
Egyebek: interfész metódus implementáció ahogy létrehoztam egy interface metódust (más mint a beépített), initialize field from contructor, create field from constructor parameter, automatikus base felhívások, var vs. típusos deklaráció konverzió, for to foreach és vissza, foreach to LINQ (durva), lambda expression, lambda statement, anon method, sima method konverziók, automata delegate-re passzoló metódus létrehozás, collapse all a solution explorerben, CTRL-T-re kódfájl keresés (nagyobb solution esetén életmentő), intellisense még nem létező, de már használt változókra, statikus class generálás, ezerféle kódelemzés, enumokhoz jobb intellisense, MVC-hez parser, stb.
Amióta nem megy, sokkal többet kell lapozgatnom a kódfájlok között, időpazarlás.
El se tudom képzelni már, hogy tudnék nélküle programozni, ennyire addict még semmilyen programtól nem lettem.
Ha az msnek lenne esze, megvenné a céget, többet ér, mint a Yahoo. :)

Defensive Database Programming ingyenes könyv

May 15th, 2010

Érdekesnek ígérkezik, ingyenes, letölthető könyv.

Szótöredék keresés SQL Serveren - furcsának ható hiba

May 13th, 2010

Az alábbi kérdezték tőlem pár perce:


SELECT [text]  FROM [table1] WHERE [text] like '%rekes%'

A rekesz szót nem találja meg, ha magyar a collation az oszlopon. Ez természetes, a kettős betűket ezzel a logikával kezeli a szerver, azaz egy betűnek tekinti őket. A where-be kell egy collation cast, mondjuk latin1-re, amiben nincsenek kettős betűk. Mondjuk ezután nem fog indexet használni a szerver, de a kezdő % miatt eleve nem használva.
Az alábbi példában az egyikkel collationnel megtalálja, másikkal nem.


SELECT [text]  FROM [table1] WHERE [text] like '%rekes%'
--  collate Hungarian_CI_AS
collate Latin1_General_CI_AS

Lehet csinálni indexelt, számított oszlopot is más collationnel, és arra szűrni, az gyorsabb lesz.

Parallel Stacks a VS 2010-ben

May 13th, 2010

Jó ez a VS 2010. Belefutottam egy problémába, amiben a Parallel stack segítsége jól jött.

Amint a képen látható az egyik szál bejár egy Dictionary-t serializálás miatt, miközben a másik beleenyúl, ettől aztán elszakad a cérna az iterátornál. Látható a képen, hogy két SaveSettings egyszerre fut, de csak az egyik seralizál, a másik, a jobbról látható vár, mert raktam be lockot.
Igen, ám, de rossz helyre! A kollekciót engedem módosítani (this[string].set), mert az a lockoláson kívül esik. Azaz a probléma a rosszul megválasztott zárolási szint (lock scope). Egy metódushívással kijjebb kell rakni, az indexerbe.

LogParser példák

May 12th, 2010

Durva gyors jószág ez a logparser, SQL Server alatt alaposan alá kellene indexelni az adatoknak, hogy ennyire gyorsan kezeljük őket.
Jó példák hozzá, meg itt és itt.

Coverage fejtörő

May 12th, 2010

A VS coverage-e ezt mutatja, hogy ez a sor csak részben van lefedve:


return (GetSourceItem(step) - this[step - 1]) * e + this[step - 1];

Nincs benne && vagy ||, akkor triviális lenne. Én már tudom a választ. :)

Update: alul, kommentben ott a megoldás.

Disable/turn off “Attach Security Warning” in Visual Studio

May 10th, 2010

Az RC óta elfelejtettem, hát leírom magamnak.

Home Windowsokon nehézkes IIS-ben fejleszteni

May 10th, 2010

Nincs bennük Windows Auth, így nem megy a debugging se. Ref. Nagy cumi ez. Ha valaki tud rá megoldást, érdekelne. (Nekem ultimate-em van, így nem gond, de már a 2. ismerősöm fut ebbe bele.)

Walkthrough: Profiling With Automated Tests

May 9th, 2010

Egyszerű, ha tudod hol kell keresni.

64 bites Office 2010 és unit tesztek

May 8th, 2010

Futtatni akartam pár régebbi unit tesztemet, de nem mentek, azt mondta, nem találja a Microsoft.ACE.OLEDB drivert. Tévesen több helyen azt láttam, hogy azt kell beírni, hogy Microsoft.ACE.OLEDB.14.0, de nem, a registryben is a régi, 12-es verzió van. Megnéztem, az InprocServer32 a C:\Program Files\Common Files\Microsoft Shared\OFFICE14\ACEOLEDB.DLL-re mutat, ami a manifestje alapján 64 bites C runtime dlleket használ, szóval tényleg van 64 bites access driver. (Az InprocServer32 név jó nagy fiaskó, minden ilyen bedrótozott verzió visszaüt később, mint a 16 bites shortParam, ami valójában 32 bites int).

Sejtettem, hogy 64 bit - 32 bit probléma van, de nem jöttem rá mi az oka, míg a tesztben ki nem írattam a teszt futtató bitszámát: Environment.Is64BitProcess == false.
Ekkor csaptam a homlokomra, hogy alapban 64 bites gépen is 32 bites processzben futnak a tesztek. De szerencsére át lehet állítani.
Ti ne töltsetek el 1 órát ilyen marhasággal, emlékezzetek erre. :)

A mai amerikai tőzsde beszakadásról

May 6th, 2010

Ma majdnem 10%-ot esett a Dow index, a többi is olyat zuhant, amilyet még nem láttam.
Az egyik cég részvényei (ACN) pár perc alatt beestek 40$-ról 0,01-ra, aztán vissza kb. 40-re. Gondolj bele, valaki megvette ekkor mondjuk 1$-ért a részvényeket, majd 5 perc múlva eladta 40x haszonnal.

Az okok között szerepel, hogy a görögök miatt be van mindenki tojva, de, és most jön az érdekes. Ekkora visszaesést mint az előbbi részvénynél nem tud okozni a pánik eladás. A pletykák szerint egy trader b-t írt be véletlenül m helyett, így az eladás (vagy short) billion lett million helyett. :) Pár nap múlva kiderül, mi volt pontosan.

Update: Kérdezték, mi történt volna, ha már menne a kereskedő algoritmusom?
Ez teljesen attól függ milyen az alg, és éppen pozícióban volt-e a zutty előtt. Vagy nagyon sokat keres, vagy sokat bukik. Waterfall profit vagy loss, az ilyen volatilitású napokon ez kiszámíthatatlan. Egyébként már rollbackelik vissza keményen a tőzsdei adatbázisokat, a tegnapi kritikus 20 perc kereskedéseit, a borokerek meg mozgatják vissza a pénzeket az accountok között, azokat, amelyek által érintett trade-k több mint 60%-kal kimásztak a korábbi árból. A tegnapi 1 centre leesett 40$-os részvény is ma már 17$-ra vissza van húzva, akinek volt pár százszoros profitja és pezsgőzött éjszaka, ma már csak 60%-os haszna maradt. Az se rossz. :)

SQL Server 2008 R2 RTM

May 3rd, 2010

Fenn van az MSDN-en, vigyük még meleg.