Archive for the ‘Szakmai élet’ Category
Monday, January 3rd, 2011
BUÉK minden kedves olvasómnak.
Az előző év eléggé bizi volt. Első félévben sok munka, második félévben ATS fejlesztés. Emiatt nem sokat blogoltam, meg semmi egyéb jelentős szakmai közösségi életet nem éltem. Emiatt az őszi MVP önértékelést be se adtam, nem szeretek úgy megkapni valamit, ha úgy érzem nem érdemeltem meg.
Így 2011. január 1-től már nem vagyok MVP. 7 évig folyamatosan az voltam, köszönöm a Microsoftnak a bizalmat és magát az elismerést.
Az idei évet most tervezem meg, próbálom meghatározni a arányokat: az ügyfélmunkák, a trading és a közösségi dolgok súlyát. Mindenesetre tervem, hogy idén újra többet fogok írni, konf előadást is vállalok, ha lesz olyan, amihez értek, így várhatóan megint többet lehet majd látni.
Sajnos az agyam egyszálú, ezért ha pl. elkezdek programolni, akkor amíg meg nem oldom az adott feladatot, addig elvonulok a világ elől, mert hajt, hogy még nincs meg a megoldás. Blogolni meg így nem lehet. Szóval idén megpróbálok ebben valami kompromisszumot kialakítani. :)
BUÉK még egyszer mindenkinek! :)
Posted in Szakmai élet, Élet | 4 Comments »
Friday, December 17th, 2010
Posted in .NET, Szakmai élet | 6 Comments »
Friday, November 26th, 2010
Mostanában elég sokat turkálok problémás webappok dumpjában. Leírom magamnak is, hogy lehet lementeni .NET stringeket a dumpból.
WinDbg dolgok következnek.
A nagy stringeket kilistáztatom a
!DumpHeap -min 100000 -type System.String
paranccsal.
Valamelyik heapről kinézek magamnak egyet, és az előbbi parancs kimenetének első oszlopában található címet felhasználva belenézek a du cím paranccsal.
Pl.
0:000> du 5ce31140
5ce31140 “*****<sitecore database=”SqlSer”
5ce31180 “ver”>.. <sc.variable name=”da”
Az elején a kuszaság (átírtam csillagokra, mert elrontotta a htmlt) a .NET Stringek adminisztrációja és az object header.
Ha szemre tetszik a string, akkor pl. ki akarom menteni fájlba.
Nézzük meg a szöveges rész előtti bináris részt (dd).
0:000> dd 5ce31140
5ce31140 793308ec 00040001 0002836c 0073003c
Az első 8 byte az object header (32 biten, 64-en ez asszem 16 byte), sync block és type leíró. Számunkra ez érdektelen. A 3. dword már érdekesebb, ez a string hozza karakterekben. Azaz bájtban ennek a duplája, mert 2 bytes unicode ábrázolást használ a .net.
Így stringünk hossza 0002836c*2 byte. A 0073003c már a < karakter (003c) és az s betű (0073), szokásos fordított Intel sorrendben.
A szöveges tartalom tehát a 5ce31140+0c címen kezdődik (headert átlépjük), és 0002836c*2 a hossza.
A tartalom fájlba írása már egyszerű:
.writemem c:\temp\s1.txt 5ce31140+0c L0002836c*2
Kedvencem a WinDbg, de ezt már mondtam. :)
Posted in .NET, CLR, Debugging, Szakmai élet | 3 Comments »
Friday, 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?
Posted in .NET, Szakmai élet | 6 Comments »
Thursday, 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
}
Posted in .NET, Szakmai élet | 2 Comments »
Thursday, 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;
}
}
}
Posted in .NET, Szakmai élet | 6 Comments »
Monday, 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.
Posted in .NET, Szakmai élet, Visual Studio, Visual Studio 2010 | 4 Comments »
Monday, 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.
Posted in .NET, .NET 4, C#, Szakmai élet | 2 Comments »
Monday, 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.
Posted in .NET, .NET 4, C#, CLR, Szakmai élet | 1 Comment »
Monday, 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. :)
Posted in .NET, Szakmai élet, Visual Studio 2010 | 3 Comments »
Saturday, May 15th, 2010
Érdekesnek ígérkezik, ingyenes, letölthető könyv.
Posted in Adatbázisok, SQL Server, Szakmai élet | No Comments »
Thursday, 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.
Posted in Adatbázisok, SQL Server, SQL Server 2005, SQL Server 2008, SQL Server 2008 R2, Szakmai élet | 3 Comments »
Thursday, 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.
Posted in .NET, .NET 4, Szakmai élet | No Comments »
Wednesday, 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.
Posted in Adatbázisok, IIS, IIS7, Szakmai élet | No Comments »
Wednesday, 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.
Posted in .NET, Szakmai élet, Testing, Visual Studio | 12 Comments »
Monday, May 10th, 2010
Az RC óta elfelejtettem, hát leírom magamnak.
Posted in Debugging, Szakmai élet, VS 2005, VS 2008, Visual Studio, Visual Studio 2010 | No Comments »
Monday, 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.)
Posted in Debugging, IIS, IIS7, Szakmai élet | 2 Comments »
Sunday, May 9th, 2010
Egyszerű, ha tudod hol kell keresni.
Posted in .NET, .NET 4, Optimalizálás, Szakmai élet, Visual Studio | No Comments »
Saturday, 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. :)
Posted in .NET, Adatbázisok, Szakmai élet, Testing | No Comments »
Monday, May 3rd, 2010
Fenn van az MSDN-en, vigyük még meleg.
Posted in Adatbázisok, SQL Server 2008 R2, Szakmai élet | No Comments »