The PIT
Röster från ITM-koncernen.

LINQ-tips

April 21, 2011 09:39 by Stefan Karlsson

Satt precis med ett litet projekt där jag laborerade med data från en GPS-puck. Datat skickade jag till en listbox för att se vad som kom från GPS-pucken:

image

Jag ville kunna spara datat till en fil och började då, precis som jag gjort 1000-tals gånger tidigare, att göra en loop som loopade igenom alla items i listboxen för att skriva ner datat till en fil. Det går självklart att göra på massor av olika sätt, nedan är de två vanligaste.

'Gammal metod 1, FOR EACH/NEXT
Dim FileContent1 As String = ""
For Each i As String In ListBox1.Items
    FileContent1 &= i & vbCrLf
Next
IO.File.WriteAllText(Application.StartupPath & "\gpsdata.txt", FileContent1)

'Gammal metod 2, FOR/NEXT
Dim FileContent2 As String = ""
For p As Integer = 0 To ListBox1.Items.Count - 1
    FileContent2 &= ListBox1.Items(p) & vbCrLf
Next
IO.File.WriteAllText(Application.StartupPath & "\gpsdata.txt", FileContent2)

 

Men så kom jag och tänka på LINQ.
Det borde gå att göra ett LINQ-fråga som skapar en array av listitems som gör att jag kan skriva ner allt till en fil med endast en rad kod. Genom att använda IO.File.WriteAllLines som tar en array av strängar och skapa en LINQ-fråga som returnerar en array av strängar från listboxens items så borde det alltså fungera, jag provade med nedanstående kod:

IO.File.WriteAllLines(filename, (From p As String In ListBox1.Items Select p).ToArray)

 

Vilket fungerade hur bra som helst! Men LINQ-frågan går att korta ner, “Select p” är vedertaget i LINQ-frågan så man behöver inte ange det, vilket gör att vi kan korta ner raden till detta:

IO.File.WriteAllLines(filename, (From p As String In ListBox1.Items).ToArray)

 

Slutsats

LINQ är häftigt, det är rent ut sagt sexigt! Men tänk på att det ibland kan vara svårt att förstå LINQ-kod, så även om den gör koden kompaktare så kan den även göra koden svårare att läsa i vissa fall, samt att man får tänka på LINQs “late evaluation”-teknik som kan ställa till det i andra sammanhang. Men i det här sammanhanget så tycker jag att LINQ gör koden mer lättläst och tar bort onödiga rader kod.

Det finns ett talesätt: Varje rad kod du INTE skriver är en rad du inte kan få en bugg i.

Over and out / Stefan


Tags:
Categories: .Net | LINQ | Tips
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Cerebrata Cloud Storage Studio

December 2, 2010 16:23 by Lars Lundin

Nytt verktyg ska underlättahantering av Windows Azure Storage

Cerebrata hartagit fram produkten Cloud Storage Studio -ett Silverlight-baserat verktyg som ska underlätta hanteringen av Windows AzureStorage.

Här är enöversiktlig beskrivning av vad verktyget klarar av:

 

  • Tabel Storage Management:
    Skapa / ta bort tabeller. Det går också att skapa / uppdatera / ta bort enheter i en tabell. Dessutom kan man skriva och köra frågor mot sina egna tabeller. 

  • Queue Management: 
    Skapa / ta bort köer. Det går även att hantera metadata som är associerat med en kö. Dessutom kan man skapa meddelanden, läsa meddelanden (32 max) och rensa bort alla meddelanden i en kö. 

  • Multiple Storage Account Management:
    Anslut till flera konton samtidigt. För att ansluta till kontot för en lagringsplats klickar man på "Logga in"-ikonen i toppen. Då öppnas inloggningsfönstret. 
    Man kan låta inloggningsinformationen sparas över flera webbläsarsessioner.
    Kontoinformationen för ditt lagringsutrymme lagras då i Silverlight Isolated Storage. 
     

 

BLOB-hantering är under utveckling och kommer att finnas i senareversion av Cloud Storage Studio.

Cloud StorageStudio finns som utvärderingsversion som kan användas i 30 dagar. Den kanhämtas hem här: http://www.cerebrata.com/


Tags:
Categories: .Net | Azure | Molnet
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Microsofts molnet-tjänst Azure

November 30, 2010 14:08 by Thomas Carlsson

(Nedan följer lite anteckningar från seminariet Azure Summit på Microsoft som Lars och Thomas har sammanställt.)

I Microsofts molntjänst Azure har man tidigare bara kunnat använda två roller: web role där man kör en website i IIS och worker role som mest kan jämföras med en Windows Service i en vanlig Windows Server där man kan köra lite allt möjligt (i princip är det så att om man kan sparka igång en EXE-fil lokalt i en Windows Server så går den att köra i en worker role).
Den nya rollen som nu kommer heter VM Role och är en Virtual Machine-roll där man alltså kan ladda upp en virtuell maskin och köra denna i Microsofts molnlösning. Denna får man då själv sen underhålla med Service Pack-uppdateringar och så vidare. Det behöver man inte göra i de två andra rollerna, men man får å andra sidan möjlighet att köra helt annan kod i sin egen virtuella maskin.
En nyhet i web role är att den nu framöver kommer innehålla en full IIS 7 så att man kan sätta upp flera websiter i samma web role. Framöver kommer man även att ha “Elevated Priviliges” som gör det möjligt att installera MSI-paket i sin web role eller worker role för att trimma serverprogramvaran med egen kod om man har behov av detta.
Remote Desktop kommer att finnas till de instanser man har.

I Windows Azure Virtual Network finns i dag tjänsten Windows Azure Connect. Denna tjänst erbjuder en säker nätverksanslutning mellan din lokala infrastruktur och Windows Azure. Denna funktion gör det lättare för en organisation att migrera befintliga applikationer till molnet genom att möjliggöra direkt IP-baserad nätverksanslutning med den egna, befintliga infrastrukturen.

Det finns även varianter på web role som heter CGI Web Role (som man använder om man ska köra PHP-sajter) och WCF Role som används för WCF-baserade tjänster.

De olika rollerna kan sen köpas i versionerna Small, Medium, Large och Extra Large där extra large är en hel bladserver med åtta processorer, large har 4 processorer, medium har två processorer medan small har en processor.
Frågan uppstår ju då om det är bättre att köpa en XL med åtta processorer direkt eller köpa åtta instanser av small med en processor i varje. Svaret på detta är inte glasklart - det beror ju lite på vad applikationen gör och hur den hanterar processorerna. Fördelen med att köpa en small som start är att man då kan skala upp till åtta instanser eller ännu mera och sen skala ner igen. Har man köpt XL-maskinen direkt så kan man givetvis skala upp den men bara skala ner till en XL-maskin.
En nyhet som kommer är även “Fulburken” - en Extra Small som man ännu inte har specifikationer på vad som begränsar den mot en Small. Meningen med denna instans är att man ska kunna använda den som en testmaskin i molnet i stället för den gamla före detta bärbara datorn som många har sparat sen de fick en ny.

Lagring
BLOB Storage (Binary Large Object Service) är till för lagring av stora filer. Det skulle exempelvis kunna handla om videoklipp och MSI-paket.
Table Store är till för strukturerad lagring i tabellform av data. Ett anorlunda sätt att lagra data för oss som är vana vid SQL Server. Här gäller denormaliserad data i egna tabeller för exempelvis order+orderrader. Denormalisering är nödvändigt för snabba sökningar då man inte kan göra joins mellan olika tabeller. Detta är billig lagring för stora datamängder som inte accessas eller förändras så ofta. Varje access av data kostar pengar.
Windows Azure Drive är en hårddisk i molnet som i sin tur lagras som en BLOB.

Meddelandehantering
Queue Service hanterar meddelanden till systemen i molnet, alla input till exempelvis en worker role bör gå via denna meddelandekö. Meddelanden plockas ur kön i ordning allt eftersom de kommer in och när den kommer till slutet börjar den om enligt en så kallad “Round Robin”-princip.

Interoperabilitet
Azure stödjer i dagsläget andra tekniker förutom Microsofts: Java och PHP. Fler kommer säkert att tillkomma.

SQL Azure
En riktig relationsdatabas för data som accessas ofta. All access av data ingår i priset för lagring av data. Priset för lagring av data är dock betydligt dyrare än Table Store. I dag finns Database, Datasync och Reporting i SQL Azure men man bygger hela tiden ut dess funktionalitet och framöver säger man att flera funktioner kommer att finnas i SQL Azure än i vanlig standard-SQL.
Management av SQL Azure kan ske från det webbaserade verktyget med kodnamn “Houston” (eller SQL Azure Database Manager som det nu heter) som är byggt i Silverlight. Detta är dock fortfarande under utveckling och kan laddas ner och köras som en CTP.
Bästa verktyget just nu för SQL Azure är SQL Management Studio för SQL 2008 R2 där man direkt kan koppla upp sig mot en databas i molnet och använda det verktyg som man är van vid.

App Fabric
Hanterar Cross Cutting Concerns för dina applikationer och innehåller detta:

Service Bus

Används till exempel när din applikation i molnet ska kommunicera med exempelvis en kunds applikation. Service Bus-tjänsten ger säker meddelandehantering och anslutningsmöjligheter som gör det möjligt att bygga ut och koppla applikationer i molnet, liksom hybrid tillämpning både på plats och i molnet. Det möjliggör användning av olika kommunikations-och meddelandetjänster, och sparar behovet av utvecklaren att oroa sig för leveranssäkerhet, tillförlitlig meddelandehantering och att hantera skalning på olika nivåer.
Access Control
Gör det möjlighet att kunna låta användaren identifiera sig med olika tjänster som t.ex Facebook, LiveID och på så sätt inte själv behöva göra all valideringsarbete.
Caching
Gör det möjligt att kunna cacha stora datamängder för snabbare access. En nackdel som de tog upp var att det inte går att cacha data som ska sparas. Dessa funktioner tillhandahålls helt som en tjänst (ingen installation eller hantering av fallen och man kan dynamiskt öka / minska cache-storleken om det behövs).
Integration
Ger gemensamma BizTalk Server-integrationsmöjligheter (till exempel rörledningar, transformer, adaptrar) i Windows Azure, med integrationsmönster out of the box för att påskynda och förenkla utvecklingen.

Intressanta länkar för den som vill fördjupa sig:
Extreme Computing Group med prestandatester för Azure-plattformen
AzureRunMe ett CodePlex-projekt för att köra vad man vill i en worker role
Windows Azure Tools for Microsoft Visual Studio utvecklingsverktyg för molnet, kräver Windows 7, VS2010 eller VS2008 med SP1
SQL Azure Tools and Labs utvecklingsverktyg för databaser
Windows Azure Architect är en online-utbildning för Azure-plattformen


Tags:
Categories: .Net | Azure | Molnet | SQL | Visual Studio
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Windows Azure – Microsofts satsning på molnet

August 31, 2010 13:39 by Lars Lundin

I många projekt har problemet varit att man inte har vetat hur mycketdatorkraft som behövts. Det kan ha gjort projekten kostsamma eftersom man antingenbetalat för en överdimensionerad miljö eller drabbats av att en underdimensioneradmiljö har kraschat eftersom trafikbelastningen blivit för hög.

Med Windows Azure erbjuder Microsoftskalbara tjänster där miljön anpassas efter de behov som tjänsten/applikationenhar.

Windows Azure kan delas in i tredelar:

·        Storage
Detta är lagringstjänsten som är nåbar via en REST API. Här finns även ettkösystem för att skicka meddelanden mellan webbtjänster och bakgrundsprocesser.

·        Compute
Hanterar webbtjänster och bakgrundsprocesser.

·        Development
Gör det möjligt att simulera Windows Azure på användarens lokala maskin.

Min personliga reflektion över WindowsAzure är att Microsoft har skapat en intressant plattform att utveckla för ochverktygen i Visual studio 2010 gör det ännu lättare för oss .NET-utvecklare. Nuska det bli intressant att se vad konkurerande molntjänster har att erbjuda.

Läs mer om Windows Azure:

http://www.microsoft.com/windowsazure/


Tags:
Categories: .Net | Azure | Visual Studio
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Open Data Protocol

March 22, 2010 13:38 by Marcus Danielsson

odataEtt av de mer spännande seminarierna jag var på under Mix10 var Open Data Protocol eller kort oData.

Det är ett API för att enkelt exponera sitt data och enkelt kunna använda det. Datat presenteras till exempel som JSON eller ATOM.

I princip kan man nå all odata direkt från en browser och alla frågor och querys mot databasen nås via REST anrop direkt i browsern. Som exempel fanns alla Mix10 sessioner och talare via oData på api.visitmix.com/OData.svc. Här kan man söka på till exempel sessioner och talare.

Allt data som finns i en Sharepoint-site kan nu nås via oData och nya Excel kan läsa oData direkt.

En site som presenterar ett oData flöde kan visa det med en ikon på samma sätt man ser att det finns ett RSS flöde.


Inslag om ITM i 19.30-sändningen av Rapport den 9e dec 2009.

December 13, 2009 16:28 by Daniel Nilsson

Mono-portalen för oss .NET-utvecklare till nya plattformar

October 5, 2009 13:54 by Lars Lundin

Android
Tack vare Koushik Dutta kan vi nu bygga och köra dotnet-applikationer på Android. Mono finns att ladda hem från Android Market och den tar upp 8 megabyte.
I skrivande stund kan endast Konsol-applikationer köras.

Läs mer om Mono:
http://www.koushikdutta.com/2009/01/mono-for-android-now-available-on.html

Mono-test på Youtube:
http://www.youtube.com/watch?v=UKanrniNCDI

 

Iphone
För Iphone finns nu MonoTouch. För mer information läs min kollega Marcus inlägg:
http://blogs.itmaskinen.se/post/2009/09/22/iPhone-utveckling-i-dotnet.aspx


Tags:
Categories: .Net | Android | Mono
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Be a microsoft professional

February 12, 2009 11:36 by Gunther Schmidt

Några tips för prov-förberedingar innför certiferingarna.

  • Läs boken som är Microsofts examensförberedelse.
  • Gör provfrågorna som följer med Boken på en CD.
  • kolla unde www.examcollection.com för nedladdningar av ytterliggare provfrågor.
  • Registrera Er med era windows Live id för en "second shot"
  • Börja inte plugga frågor för fullt tidigare än 3 dagar innan själva provet. Annars är de bara förvirrande i slutändan.
  • Lugna er och gå på spa kvällen innan och ta en öl! Om ni klarar av att inte vara nervös då har ni redan 50% rätt.

Gunther


Tags:
Categories: .Net | ASP | Press | Visual Studio
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Beräknad väntetid: 5 minuter.

February 3, 2009 13:00 by Stefan Karlsson

 

Implementerade precis “beräknad väntetid” i vårt köhanteringssystem, ni vet ett sådant där kunden trycker fram ett könummer och sedan väntar på att just det numret ska visas upp på en display så man vet vilken kassa man ska gå till. 

Det förvånade mig att det fanns så många sätt att beräkna just denna väntetid på, många uppenbarligen felaktiga också.

För tydlighetsskull så benämner jag det nummer som kunden får fram på sitt kvitto för TicketNumber och det nummer som kassören matar fram för QueNumber. QueNumber är alltså det nummer som just nu ska betjänas, det kan aldrig vara större än NextTicketNumber (Sista utskrivna TicketNumber+1).

Skillnaden i värde mellan QueNumber och NextTicketNumber är alltså detsamma som antalet kunder som står och väntar på att bli betjänade.

Variant 1

Min första approach var att varje gång en kassör matar fram ett QueNumber i kassan så sparas kassaid, quenumber och en timestamp i en tabell och därefter så är det lätt att få fram hur lång tid det tog mellan varje frammatning och på så sätt få fram en “velocity”, antal frammatningar per timme. Om man räknar fram att man har 10 frammatningar per timme och sedan tar NextTicketNumber-QueNumber (för att få fram antal väntande kunder) så kan man med den informationen räkna ut hur lång genomsnittlig väntetid det blir för de väntande kunderna. För att minska eventuella avvikelser när busslaster kommer så kan man öka tiden man beräknar på till två timmar.

En stored procedure tog snabbt fram detta:

CREATE PROCEDURE GetQueWaitTime AS 
declare @NextTicketNumber int
select @NextTicketNumber=countervalue from skibarcounters where countername='nextticketnumber'
declare @NextQueNumber int
select @NextQueNumber=countervalue from skibarcounters where countername='NextQueNumber'
declare @TicksPerTwoHours int
select @TicksPerTwoHours=count(*) from questamps where datediff(n,stamp,getdate())<120
select 120/@TicksPerTwoHours   * (@NextTicketNumber-@NextQueNumber)

 

Uppenbara nackdelar med denna metoden:

  • Om man inte haft kunder på två timmar, eller väldigt få, så blir antal frammatningar per två timmar 0 eller nära 0, vilket gör att man får en falsk väntetid. Dvs, har man bara haft två kunder så kan det bli så att systemet antar att väntetiden är 30 minuter per kund och kommer det sedan in 10 kunder så kommer systemet visa helt felaktiga väntetider mot verkligheten.
  • Början av dagen när man inte haft några kunder så kommer det inte att finnas tillgängliga data och problemet som uppstår i punkt 1 kommer att uppstå här också.
  • Har man haft kunder och man får fram en genomsnittlig tid på 5 minuters väntetid och sedan har en dödperiod så kommer de där 5 minutrarna att öka hela tiden tills man börjar mata fram nya nummer. Det är inte verklighetsbaserat att väntetiden per kund ska öka bara för att man inte råkar ha några kunder att betjäna.

      Variant 2

      Vi insåg att vi var tvugna att spara ner tidpunkten för när kunden trycker fram sitt nummer, vi modellerade om tabellen lite så att när kunden trycker fram ett TicketNumber så lagras numret och tidpunkt för utskrift och när kassan trycker fram ett QueNumber så uppdateras den raden med kassaid och tidpunkt för betjäning samt en uträknad diff i minuter mellan dessa två tidpunkter. (Genom att matcha mot kvitton skapade i kassan kan man därefter också få fram hur lång tid det tog att betjäna kunden, men det är en annan sak)

      Nu räckte det alltså med en enkel fråga för att få fram genomsnittlig tid, vi nöjer oss med att kolla genomsnittlig faktisk väntetid den senaste timmen, fältet WaitedTime är det uträknade antal minuter kunden fick vänta mellan han tryckte ut sitt könummer och tills könumret visades i displayen, vi kollar bara rader som har ett cashierid som skiljer sig från 0 för det är bara de som blivit “frammatade”:

      select avg(waitedtime) as waitminutes from questamps where

      cashierid<>0 and datediff(n,stamp,getdate())<60

       

      Jag kände mig ganska nöjd med den här lösningen först men sen när jag sovit en natt så kom jag på att denna variant inte tar hänsyn till hur många kunder som står och väntar just nu. Den gör bara halva arbetet, den säger att Senaste timmen var den genomsnittliga väntetiden 5 minuter. Men om det kommit in en ny busslass med personer så att det står 40 personer och väntar så applicerar den inte kunskapen på detta.

      Lösningen är så klart att plocka fram antalet väntande kunder och applicera den genomsnittliga väntetiden på dessa och visa ett modifierat tal för detta.

      Med den modifikationen känns det som att vi har en pålitlig uträkning för att få fram en genomsnittlig väntetid som både tar hänsyn till historik och nuvarande kösituation.

      Det jag skulle vilja lägga till för att förbättra rutinen är att man först filtrerar bort stora avvikelser, t.ex. tar bort de som avviker i tid med mer än x% från genomsnittstiden osv. För att det inte påverkar allt för mycket när 4 busslaster med danskar stormar in. Men det kan man finetune efter att man fått in lite mer verkliga data att titta på.

      Utmaning

      Har du något bättre sätt att få fram en pålitlig siffra eller en helt annan approach (jag har minst 3 varianter till att räkna ut siffran på, mer eller mindre felaktiga eller med falska utslag av väntetider osv) så kommentera gärna artikeln.


    Tags:
    Categories: Programmering | .Net | SQL
    Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

    Double vs Decimal

    November 25, 2008 10:37 by Stefan Karlsson

     

    Se nedanstående kod:

            Dim x As Double = 3.65
    
            Dim y As Double = 0.05
    
            Dim z As Double = 3.7
    
            MsgBox((x + y) & " - " & z) ' 3.7 - 3.7
    
            MsgBox((x + y) = z) ' False

     

    Som ni ser så evalueras x+y till 3.7 och när man jämför det med z som också är 3.7 så får man FALSE. 3.7 är alltså inte lika med 3.7.

    Ändra ovanstående kod till att använda Decimal istället:

            Dim x As Decimal= 3.65
    
            Dim y As Decimal = 0.05
    
            Dim z As Decimal = 3.7
    
            MsgBox((x + y) & " " & z) '3.70 - 3.7
    
            MsgBox((x + y) = z) 'TRUE

     

     

    Nu är helt plötsligt x+y samma som z.

     

    Det är alltså viktigt att förstå att Double inte alltid beter sig som man kan tro och om man nu skulle använda Double för att hantera t.ex. pengar och i ett program kontrollera om betalt belopp är samma som fakturerat belopp så kan man få oanade konsekvenser.

    Varför det blir på det här viset förklaras närmare på nedanstående länk:

    http://www.yoda.arachsys.com/csharp/floatingpoint.html

     

    Happy coding!

    /Stefan


    Tags:
    Categories: Programmering | .Net
    Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed