MAGAZINE. IN DIT NUMMER O.A.:

Maat: px
Weergave met pagina beginnen:

Download "MAGAZINE. www.sdn.nl IN DIT NUMMER O.A.:"

Transcriptie

1 MAGAZINE SOFTWARE DEVELOPMENT NETWORK ISSN: IN DIT NUMMER O.A.: Full text search met Lucene op Azure < Async/await en het restaurantmodel < Talking about Frames < Continuous Deployment met TFS, Octopusdeploy en Azure < Application Insights for Visual Studio Online < Nummer 121 juni 2014 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network 121

2

3 Colofon Uitgave: Software Development Network Tweeëntwintigste jaargang No. 121 juni 2014 Bestuur van SDN: Marcel Meijer, voorzitter Rob Suurland, penningmeester Remi Caron, secretaris Redactie: Marcel Meijer Aan dit magazine werd meegewerkt door: Roel Hans Bethlehem, Bob Swart, Maarten van Stam, Arjen Bos, Alexander Meijers, Remi Caron, Marcel Meijer en natuurlijk alle auteurs! Listings: Zie de website voor eventuele source files uit deze uitgave. Contact: Software Development Network Postbus 506, 7100 AM Winterswijk Tel. (085) Fax (085) Vormgeving en opmaak: Reclamebureau Bij Dageraad, Winterswijk Alle rechten voorbehouden. Niets uit deze uitgave mag worden overgenomen op welke wijze dan ook zonder voorafgaande schriftelijke toestemming van SDN. Tenzij anders vermeld zijn artikelen op persoonlijke titel geschreven en verwoorden zij dus niet noodzakelijkerwijs de mening van het bestuur en/of de redactie. Alle in dit magazine genoemde handelsmerken zijn het eigendom van hun respectievelijke eigenaren. Adverteerders Microsoft 2 Achmea 40 Beste SDN magazine lezer, voorwoord De Olympische spelen zijn inmiddels afgelopen, maar de Oranje gekte gaat de volgende fase in. Want de wereldkampioenschappen Voetbal beginnen zeer binnenkort in Brazilië. De tenniswedstrijden op Roland Garos en Wimbledon zijn voor ons Nederlanders in het verleden ook mooie toernooien geweest. Maar deze trekken naast het wereldkampioenschap Hockey in Den Haag, de Giro in Italië en de Tour de France toch minder bekijks en spreken minder tot de verbeelding dan het Voetbal. Als je het zo bekijkt is het een aaneenschakeling van sportevenementen voor elk wat wils. Onze ICT wereld is dat eigenlijk ook. Is de ene release geweest, dan staat de volgende op het punt het levenslicht te zien. Hebben we net de Build Conference gehad met de verschillende aankondigen, worden er in Teched Noord Amerika weer nieuwe aankondigingen gedaan. En als je dan denkt dat het even rustig is, dan komen Apple of Google of Delphi met hun Conferenties en hun nieuwtjes. Kortom ook dit is een aaneenschakeling van aankondigingen en nieuwe producten. Zeker nu we bijna allemaal gebruik maken van een Agile manier van werken, volgen de vernieuwingen elkaar nog sneller op. Hierdoor gaat de wereld sneller dan enige jaren geleden. Voor een jong vakgebied is dat best knap. Om bij te blijven en op de hoogte te blijven van de nieuwste ontwikkelingen proberen wij je met ons magazine volledig up-to-date te houden. Ook dit magazine staat weer boordevol met nuttig en bruikbare informatie. Onze auteurs hebben allemaal stuk voor stuk hun uiterste best gedaan om mooie, aansprekende en informerende artikelen te maken. Ik vind dat ze daarin zijn geslaagd. Zo hebben we artikelen over Async programmeren, Dynamic Frames met Delphi, het nieuwe Application Insights van Visual Studio Online, Column over Agile van Sander, Hoe nog beter te kunnen samenwerken door een stukje toegevoegde techniek, coolere website met HTML5, Column van Michiel over de Wolkenarchitect, Remote applications on Microsoft Azure, hoe Lucene te gebruiken op Azure, Delphi XE5, de combinatie van Continous deployment met TFS en Octopusdeploy en wat kleine nieuwtjes over het Microsoft Azure platform. Kortom een lekker dik nummer met mooie artikelen. Graag horen we welke artikelen jullie zelf zouden willen schrijven. Er zit een auteur in ons allemaal. Veel leesplezier en mail ons jullie vragen cq. opmerkingen. Groeten, Marcel Eindredacteur Magazine en Voorzitter SDN Adverteren? Informatie over adverteren en de advertentietarieven kunt u vinden op onder de rubriek Magazine. magazine voor software development 3

4 Agenda 2014 Inhoud 6 juni 2014 SDN event 2 22 augustus 2014 SDN magazine september 2014 SDC/SDE oktober 2014 Teched (Barcelona) 14 november 2014 SDN magazine 123 medio december 2014 SDN event 3 03 Voorwoord Marcel Meijer 04 Inhoudsopgave 04 Agenda 05 Full text search met Lucene op Azure Roy de Boer en Freek Paans 10 Working software over proce$$es and fools Sander Hoogendoorn 13 Delphi REST Client Components Bob Swart 16 Async/await en het restaurantmodel Piet Amersfoort 20 Talking about Frames Cary Jensen 24 Applicatiestack opnieuw uitvinden met HTML5 Niels Bergsma 26 Continuous Deployment met TFS, Octopusdeploy en Azure Eric Tummers 31 Wolkenarchitect Michiel van Otegem 32 Reach further by developing collaboratively Isak Edblad 34 Application Insights for Visual Studio Online Hassan Fadili 38 Microsoft Azure Remote Apps Marcel Meijer

5 CLOUD Roy de Boer en Freek Paans Full text search met Lucene op Azure Lucene is een full text search engine, oorspronkelijk geschreven in Java. Het biedt mogelijkheden om grote hoeveelheden tekst efficiënt te doorzoeken. In dit artikel beschrijven we onze ervaringen met het inzetten van Lucene.NET (een populaire.net port van Lucene) binnen een Azure-omgeving, de cloud-oplossing van Microsoft. Azure stelt namelijk een aantal specifieke eisen aan de architectuur van een applicatie, die ook van invloed zijn op de Lucene implementatie. We stellen daartoe een dergelijke architectuur voor en onderzoeken een aantal karakteristieken hiervan. Bij dit artikel hoort een voorbeeldproject, waarin we de publieke domein boeken van gutenberg.org doorzoekbaar maken. In dit voorbeeldproject passen we de voorgestelde architectuur toe. Daarnaast kan dit project ook als basis dienen om zelf verder met Lucene op Azure te experimenteren. Het project is te vinden op We zullen nu beginnen met een korte review van de Lucene API, waarna we ingaan op de Azure-specifieke uitdagingen. Vervolgens tonen we een mogelijke implementatie en sluiten af met een analyse van de operationele karakteristieken van die implementatie. Lucene Vroeger was het gebruikelijk om informatie te zoeken aan de hand van sleutelwoorden in een kaartenbak. Dit was beter dan niets, maar met de komst van zoekmachines is het gebruikelijk geworden om informatie te zoeken op basis van willekeurige tekstfragmenten. Dit concept staat bekend als full text search. Mocht je zelf full text search willen aanbieden om applicatie-specifieke informatie doorzoekbaar te maken, dan bieden veel databases daar standaard mogelijkheden voor. Als die mogelijkheid er echter niet is, zoals in Azure SQL Database, dan bestaan er ook externe componenten die dit kunnen, zoals Lucene. Dit is een populaire keuze voor Java-projecten, en wordt onder andere gebruikt door Solr en ElasticSearch. Daarnaast is het project inmiddels ook naar.net geport, deze port gebruiken we voor dit artikel. Lucene Document Waar binnen een relationele database een record de kleinste eenheid van opslag is, is dat binnen Lucene een Document. Dit is een datastructuur waarmee je de te doorzoeken data in één of meerdere velden kunt onderbrengen. Naast deze zelf te definiëren velden, houdt Lucene ook een intern ID bij voor elk document. Dit ID zullen we later terugzien bij het ophalen van resultaten. Zo maken we in het voorbeeldproject per boek een document aan, met daarin de volgende velden: Gutenberg ID, titel, publicatiedatum op Gutenberg, taal, auteur en de volledige tekst van het boek. Dit maakt het mogelijk om bijvoorbeeld specifiek op Gutenberg ID of taal te zoeken. IndexReader en IndexWriter Lucene slaat alle documenten op in de zogenoemde index. Net als bij bijvoorbeeld een relationele database zorgt de index ervoor dat er efficiënt gezocht kan worden. Het uitlezen van en wegschrijven naar deze index wordt respectievelijk door de classes IndexReader en IndexWriter verzorgd. Deze classes zijn ontworpen met multithreaded applicaties in het achterhoofd: een enkele instantie kan worden gedeeld tussen alle threads binnen de applicatie zonder dat je zelf voor synchronisatie hoeft te zorgen. In verband met performance en geheugengebruik wordt geadviseerd om met één instantie per applicatie te werken. In ieder geval kan de fysieke index maar door één IndexWriter tegelijkertijd worden bewerkt. In het algemeen is de geïndexeerde informatie, en zo ook de Lucene index, aan verandering onderhevig. IndexReader detecteert wijzigingen niet automatisch. De wijzigingen worden pas zichtbaar na het aanmaken van een nieuwe instantie. Hoe we hier mee omgaan, laten we verderop in het artikel ook zien. Query en IndexSearcher Zoekopdrachten binnen Lucene worden gëencapsuleerd in een Query object. Een dergelijk object is op meerdere manieren te verkrijgen, bijvoorbeeld via de QueryParser class die een tekstuele query zoals titel:max AND auteur: mult* vertaalt naar een Query. Maar er is bijvoorbeeld ook de TermQuery. De Query kan vervolgens door de Search methode van de class IndexSearcher worden uitgevoerd. Dit levert een op relevantie gesorteerde lijst met Lucene Document ID s op. IndexSearcher is net als IndexReader en IndexWriter threadsafe, waardoor één instantie per applicatie voldoende is. Directory Toegang tot de fysieke index wordt geregeld door implementaties van de abstract class Directory, zoals bijvoorbeeld FSDirectory of RAMDirectory (die de index respectievelijk op het filesystem of in RAM opslaan). Tot zover de review van de Lucene API. We gaan nu verder in op de Azure-specifieke uitdagingen. magazine voor software development 5

6 CLOUD Uitdagingen op Azure Om Lucene te gebruiken op Azure moet je rekening houden met een aantal uitgangspunten van Azure: In een Azure-omgeving moet je elk logisch onderdeel van je systeem op minimaal twee nodes draaien om aanspraak te kunnen maken op de SLA van 99.95% beschikbaarheid. Zo zul je minimaal twee nodes van je web- of worker-roles nodig hebben. Binnen de Azure-rollen heb je te maken met een transient harddisk. Dat wil zeggen dat bestanden die je wegschrijft op het lokale filesystem niet durable zijn; als Azure de node re-imaged krijg je weer een kaal filesystem. Aangezien Azure dit op willekeurige tijden doet, moet je hier rekening mee houden bij het ontwikkelen van je applicatie. Voor het gebruik van Lucene heeft dit een aantal implicaties. Een request als GET /Search?q=foo+bar komt namelijk op een willekeurige web-node uit. De node in kwestie zal toegang moeten hebben tot de fysieke index om het request af te kunnen handelen. In een dergelijke multi-node situatie zijn er twee voor de hand liggende opties voor de locatie van de index: ofwel het lokale filesystem, ofwel een shared storage, in het geval van Azure bijvoorbeeld de Windows Azure Blob Storage. De oplossing met het lokale filesystem is vrij complex omdat je zelf de index op de diverse nodes gesynchroniseerd moet houden. Je loopt dan al snel tegen situaties aan waar je gebruik moet maken van gedistribueerde transacties om de indices consistent te houden. Een ander probleem is het initialiseren van een kale node, bijvoorbeeld omdat een node wordt toegevoegd, of een bestaande node opnieuw wordt ge-imaged. In dergelijke situaties moet je de index herbouwen, wat afhankelijk van de grootte een tijdrovende klus kan zijn. We hebben daarom gekozen voor de oplossing waar we de index delen via een shared storage. Hierbij zullen de indices wel altijd in-sync zijn. Er kleeft echter ook een nadeel aan: elke node moet updates kunnen doorvoeren op de index, terwijl er maar één actieve Index Writer kan zijn. In principe regelt Lucene deze synchronisatie zelf via locking, maar nodes moeten hierdoor op elkaar wachten. Hierdoor kunnen de responsetijden oplopen en kunnen er uiteindelijk zelfs time-outs optreden. Dit probleem is op te lossen door één proces aan te wijzen dat alle writes doet. Andere nodes geven dan hun gewenste wijzigingen door aan dit proces. In onze implementatie noemen we dit proces de Indexer, en communiceren we de updates via een queue. Nadeel van deze oplossing is wel dat je eventual consistency introduceert: na een write zal het even duren voordat deze zichtbaar is op elke node. De tijd tussen het doorgeven van een wijziging en het daadwerkelijk zichtbaar worden op een web-node noemen we de update-latency. Een ander probleem is dat de index niet op het lokale filesystem leeft en de daarom benodigde netwerktoegang tot de shared storage extra latency zal opleveren. Dit probleem zou je kunnen verzachten door de index lokaal te cachen. Lucene leent zich hier goed voor omdat updates incrementeel te downloaden zijn. Beide oplossingen voor de genoemde problemen worden geïmplementeerd door de vrij beschikbare component AzureDirectory ( Dit is een implementatie van de Lucene Directory die de index opslaat op de Blob Storage. Bovendien wordt de index ook in een cache op het lokale filesystem bijgehouden. Een complete oplossing zou er dan zo uit kunnen zien: In dit schema valt op dat er twee Indexer nodes zijn (waar het Indexer proces op draait), dit is nodig vanwege de Azure SLA voorwaarden. We leggen later uit hoe we zorgen dat er slechts één actief is. We zullen nu de geschetste architectuur verder uitwerken en onderzoeken. Implementatie Er zijn twee aspecten waar een wezenlijk verschil ontstaat tussen deze architectuur en een single-node situatie: het doorvoeren van updates en het verversen van de IndexReader. Omdat ons artikel specifiek gaat over Lucene op Azure zullen we deze aspecten verder uitdiepen. Index updates Een update op de index bestaat uit twee stappen: allereerst wordt de gewenste update gequeued door een web-node, waarna hij wordt gedequeued en aan de index wordt toegevoegd door het Indexer proces. Het queuen gebeurt, in pseudocode, als volgt: Book book = ; Queue queue = ; queue.enqueue(serialize(book)); Het verwerken van de update ziet er dan zo uit: IndexWriter writer = ; Queue queue = ; Message message = queue.dequeue(); Book book = Deserialize(message.Body); writer.adddocument(tolucenedocument(book)); writer.commit(); message.complete(); De call naar Message.Complete wordt gedaan omdat er gewerkt wordt met een peek-lock pattern. Dit voorkomt verlies van berichten bij fouten tijdens de verwerking. Het is dan wel belangrijk om Message.Complete pas na writer.commit aan te roepen. Azure Service Bus Queues biedt deze peek-lock semantiek en gebruiken we dan ook in onze implementatie. De API s van Lucene en de Service Bus bieden beide mogelijkheden tot batchverwerking. Wanneer er meerdere berichten beschikbaar zijn 6 MAGAZINE

7 CLOUD in de queue kunnen deze in één keer worden verwerkt. Zoals we straks laten zien heeft dit invloed op de performance. De batch size noemen we B. Dat ziet er dan zo uit: IndexWriter writer = ; Queue queue = ; int batchsize = ; Message[] messages = queue.receivebatch(batchsize); foreach (var message in messages) { AddMessageToIndex(writer, message); writer.commit(); queue.completebatch(messages); Bij het bepalen van de batch size kijken we naar de verwerkingssnelheid van de Indexer en naar de update-latency : function GetIndexWriter() { Directory directory = Ö; while (true) { try { return new IndexWriter (directory); catch (LockObtainFailedException) { Sleep(Ö); De LockObtainFailedException treedt op wanneer een Indexer-node al een IndexWriter open heeft op de index. Met deze constructie kan er dus altijd maar één Indexer-node berichten verwerken. Verversen van de IndexReader Voor het lezen van de index implementeren we een IndexReader singleton: class IndexReaderSingleton { static _indexreader = new IndexReader(..) static GetInstance() { return _indexreader; We zien dat een batch size van minder dan B=200 berichten de verwerkingssnelheid beperkt. Voor batch sizes groter dan 200 neemt de verwerkingssnelheid niet meer toe. De optimale verwerkingssnelheid is dus te bereiken door de batch size op minimaal B=200 berichten te stellen. Als er updates plaatsvinden op de index worden deze pas zichtbaar als we een nieuwe IndexReader openen. We hebben voor een strategie gekozen waarbij de IndexReader periodiek, dus elke x seconden, opnieuw geopend wordt. Dit zorgt er dus voor dat we elke x seconden een verse IndexReader hebben. We noemen die periode de verversperiode R. Het verversen gaat dan als volgt: class IndexReaderSingleton { static Refresh() { _indexreader = new IndexReader( ); Schedule.Every(x seconden, IndexReaderSingleton.Refresh) We hebben voor de overzichtelijkheid synchronisatie- en lockingoverwegingen buiten beschouwing gelaten. We hebben ook gekeken hoe de update-latency zich bij verschillende aanvoersnelheden v (updates per seconde) gedraagt: We zien dat er voor batch sizes groter dan 175 berichten geen significant verschil in update-latency is bij deze aanvoersnelheden. We zien ook dat rond de 100 updates per seconde verzadiging van de queue plaatsvindt en dat de latencies daardoor oplopen. Dit strookt met de observaties met betrekking tot de verwerkingssnelheid. Een laatste overweging bij implementatie is de Azure SLA: het proces dat schrijft zal ook dubbel uitgevoerd moeten worden, maar er mag slechts één IndexWriter tegelijkertijd actief zijn. Dit lossen we op door het synchronisatiemechanisme van Lucene te gebruiken: Een nadeel van deze oplossing is dat we steeds een compleet nieuwe IndexReader openen, wat potentieel duur is. We benutten daarom de Reopen()-methode van de IndexReader, deze methode vult de door de huidige IndexReader geladen data aan met nieuw beschikbare informatie. class IndexReaderSingleton { static Refresh() { _indexreader = _indexreader.reopen(); Voor het uitvoeren van zoekopdrachten hebben we tot slot de Index- Searcher nodig. Deze heeft een afhankelijkheid op de IndexReader en daarom laten we de lifecycle van de IndexSearcher samenlopen met die van de IndexReader. magazine voor software development 7

8 CLOUD class IndexSearcherSingleton { static _indexreader = new IndexReader(Ö) static indexsearcher = new IndexSearcher(_indexReader); static Refresh() { IndexReader newreader = _indexreader.reopen(); if (newreader == _indexreader) { return; _indexreader = newreader; indexsearcher = new IndexSearcher(_indexReader) static GetInstance() { return _indexsearcher; We maken hierbij gebruik van het feit dat _indexreader.reopen zichzelf teruggeeft als de index onveranderd is. Een zoekopdracht neemt dan de volgende vorm aan: IndexSearcher indexsearcher = IndexSearcherSingleton.GetInstance(); string userquery = ; Query query = new QueryParser( ).parse(userquery); TopDocs topdocs = indexsearcher.search(query, ); TopDocs bevat dan de lijst met de meest relevante Lucene Document ID s. Dan moeten we nog een keuze maken voor de waarde van de verversperiode R. Om dit te bepalen bekijken we hoe de updatelatency hierdoor beïnvloed wordt bij verschillende aanvoersnelheden v. We zien dat de aanvoersnelheid in de gevallen v=0, v=10, v=20 updates per seconde geen significante invloed heeft op de updatelatency bij verschillende verversperiodes. Voor een aanvoersnelheid van v=50 updates per seconde zie je een hogere latency voor verversperiodes kleiner dan 2000 ms, dan voor 2500 ms. We hebben dit verder niet onderzocht. Daarnaast zien we dat de update-latency in de overige gevallen lineair schaalt met de verversperiode. Een tweede overweging is de interactie met de Blob Storage. We hebben daarom gemeten hoeveel data er vanaf de Blob Storage gedownload wordt per web-node, uitgezet tegen de tijd. Tijdens deze meting was de aanvoersnelheid 75 updates per seconde: We zien dat de verversperiode geen significante invloed heeft op de hoeveelheid gedownloade data. Overigens zijn de duidelijke stappen in de grafiek toe te schrijven aan het index merge proces van Lucene. Dit proces optimaliseert de fysieke index door onder andere data samen te voegen. Deze samengevoegde data staat dan niet in de cache, en moet dus in zijn geheel gedownload worden. De initiële download is 465 MB, wat ruwweg overeenkomt met de grootte van de index op de Blob Storage, 425 MB. Er blijkt dus dat een verversperiode van 2500 ms voor alle onderzochte aanvoersnelheden resulteert in een update-latency van lager dan 4 seconden. Daarbij levert dit ten opzichte van langere verversperiodes geen groot verschil op in traffic naar de Blob Storage. We hebben echter het gebruik van systeemresources niet gemeten en kunnen ons voorstellen dat er problemen kunnen ontstaan bij korte verversperiodes, vooral wanneer je het opruimen van de IndexReader en Index- Searcher overlaat aan de garbage collector. Dit lichten we hieronder verder toe. Dispose versus GC In bovenstaande implementatie laten we het opruimen van de oude IndexReader en IndexSearcher over aan de garbage collector.dit kan ervoor zorgen dat sommige resources (zoals files) onnodig lang geopend blijven. Als dit een probleem blijkt kun je ervoor kiezen om de Dispose()-methodes van IndexSearcher en IndexReader aan te roepen na gebruik. Pas echter op: meerdere threads kunnen een reference hebben naar deze objecten en Dispose() mag pas aangeroepen worden nadat alle threads hebben aangegeven klaar te zijn met hun reference. Een methode om dit te doen is het gebruik van reference counting. Een mogelijke implementatie hiervan tonen we in het voorbeeldproject. Operationele karakteristieken Als laatste zijn we geïnteresseerd in de operationele eigenschappen van deze oplossing. We kijken daarvoor naar enkele omgevingsparameters: wat is de invloed van het aantal gebruikers op de zoeksnelheid, en wat is de invloed van het aantal documenten op de update-latency. 8 MAGAZINE

9 CLOUD We hebben gemeten hoe de zoekperformance schaalt met het aantal zoekende gebruikers (gesimuleerd met meerdere threads) bij twee verschillende indexgroottes N (aantal documenten in de index). We doen dit door te zoeken op willekeurige zoektermen en de 10 meest relevante resultaten op te vragen: We zien dat een concurrency tot 25 threads per node in beide gevallen een zoeklatency van minder dan 100 ms oplevert. Bij documenten is er nog ruimte voor hogere concurrency bij gelijke zoeklatency. Voor documenten is dit echter niet het geval; daar loopt de zoeklatency snel op. Het aantal concurrent zoekopdrachten dat je per node kunt bedienen wordt dus beperkt door de indexgrootte. Tenslotte onderzoeken we hoe de update-latency zich gedraagt bij verschillende indexgroottes. Hiertoe meten we de update-latency als functie van het aantal documenten in de index N, bij verschillende aanvoersnelheden v. Dit hebben we verder niet onderzocht. De updatedoorvoersnelheid van 100 updates per seconde is in onze gevallen toereikend geweest. We hebben daarom niet onderzocht of we deze nog hoger konden krijgen. De Indexer lijkt wel moeilijker uit te schalen omdat er maar één Indexer actief kan zijn. Deze eigenschappen maken dat wij Lucene een geschikte oplossing vinden voor het aanbieden van full text search in een Azure-omgeving. In de praktijk zetten wij de geschetste oplossing met succes in binnen meerdere projecten. We zijn hierbij niet tegen grote verrassingen aangelopen en zullen Lucene blijven overwegen voor nieuwe projecten. Roy de Boer Roy de Boer (roy@infi.nl) is één van de oprichters van Infi. Naast een voorliefde voor C#, en de oneindige tocht naar elegant softwareontwerp, is hij ook nogal enthousiast over OS X en FreeBSD. Freek Paans Het blijkt dat het aantal documenten in de index geen significante invloed heeft op de update-latency. Daarnaast is de gemeten ondergrens van de update-latency 2.0 s. Conclusie We hebben de Lucene API in het kort geïntroduceerd en de problemen om deze op Azure in te zetten uiteengezet. Vervolgens hebben we een architectuur die deze problemen oplost voorgesteld en de karakteristieken hiervan doorgemeten. We hebben de volgende observaties gedaan voor een implementatie die gebruik maakt van Azure Service Bus voor queueing en Azure Blob Storage voor persistent storage voor de index: De zoeklatency is bij indices tot documenten en een concurrency van 25 threads minder dan 100 ms. De indexgrootte heeft een duidelijke invloed op de zoeklatency: grote indices hebben in het algemeen een hogere latency en beperken bovendien de concurrency per node ten opzicht van kleinere indices. De indexgrootte heeft geen significante invloed op de updatelatency. We kunnen tot 100 updates per seconde op de index doorvoeren, hiervoor is wel een batch size van minimaal 200 berichten vereist. Bij een verversperiode van 2.5 s zien we een update-latency van 4 seconden. De traffic van de Blob Storage wordt niet significant beïnvloed door de verversperiode. Lucene op Azure is daarmee binnen onze projecten een schaalbare oplossing gebleken. Binnen een node vinden wij de performance van Lucene acceptabel en je ziet bovendien ook lineair gedrag bij het bijschakelen van web-nodes. Uiteindelijk zal de Blob Storage waar de index op staat mogelijk een bottleneck worden. Freek Paans (freek@infi.nl) werkt als technisch directeur bij Infi. Hij houdt zich voornamelijk bezig met het optimaliseren van het softwareontwikkeltraject binnen Infi, maar typt ook nog actief mee aan verschillende projecten. Verder vindt hij het leuk om na te denken over vrijwel elk vraagstuk in de softwareontwikkeling: van low-level performancewerk tot teamorganisatie tot conceptontwikkeling. Freek is ook te vinden op twitter 1 We gebruiken in de metingen documenten tussen de 0 en 3 kb. Mocht je meer vragen hebben over de meetmethode dan kun je deze per mail aan ons stellen. TIP: Downloaden SDN Magazines Op de site van SDN vind je niet alleen een archief van alle magazines, het is ook mogelijk om de magazines te downloaden: magazine voor software development 9

10 GENERAL Sander Hoogendoorn Working software over proce$$es and fools Quite frequently people in agile (and non-agile) projects or at conferences and workshops come up to me and ask me what tooling they should use. Which online agile dashboard tooling do you recommend us?, What is the best code repository? or even We are doing a Scrum project. Are we allowed to use a UML modeling tools such as Enterprise Architect in Scrum? In all situations, I reply using the all-time favorite Scrum Master - which I m not and never will be - response: it depends. Not because I don t know much about agile tooling, but because there s many different sides to the subject. To be honest, in my opinion, the discussion around agile tooling is expanding faster than the universe. Agile hippies and Scrumdamentalists First of all, there are groups in the agile community - if there ever was a single one - with highly idealistic attitudes, where people have this almost John Lennon-esque view of how agile will make the world a better place and will bring world peace at last. This is a world where all tools are considered evil, and are comparable to releasing drones in Afghanistan. A world where using tools feels cheating. These agile hippies as I refer to them rely heavily on the left side of the Agile Manifesto. This is where Working software over comprehensive documentation turns into No, we do not document in agile projects, and where Individuals and interaction over processes and tools become No, you re not allowed to use a modeling tool in an agile project. To me, although this is an interesting view, it is also a rather naïve way of looking at the world of agile. Next, there are what I refer to as the Scrumdamentalists. With the rising popularity of agile and agile approaches such as Scrum and now Agility Path - basically Scrum but with the word enterprise added to the names of all the roles and deliverables - many newbies have enrolled in Scrum Mastery; well-willing people with brand new certificates but hardly any real-life experience in agile projects. Scrumdamentalists will follow the Scrum Guide, which they consider to be their bible, quite literally. Now the Scrum Guide is an interesting read as it comes to tooling, as it hardly discusses tooling. The Scrum Guide does not refer to unit testing frameworks, or how to set up your dashboard, or even where to store your user stories. In fact, the Scrum Guide does not even mention user stories. At all. The agile suits On the other, total opposite side of the spectrum, we find the vendors. Agile is more and more becoming a vehicle to make money. We already had a plethora of monopolized certification programs - or scams if you wish - to make money from, but more recently we are seeing that agile principles and techniques are penetrating board rooms of large enterprises. Hence the sudden need from agile methodologists to quickly come up with enterprise agile approaches. Think Disciplined Agile Delivery, SAFe and Agility Path - which, with the risk of being called blasphemous, you could describe as the Scrum Guide with the word enterprise taped to it. And when there s enterprises involved, there s tools to be sold, and there s money to be made. So the vendors, which I refer to as the agile suits, enter the agile arena as well. Some vendors are achieving this by displaying agile street credibility, such as Atlassian, who print t- shirts for nerds -yes, which I do wear and send funny videos on how to pair program out on YouTube. 10 MAGAZINE

11 GENERAL As you can imagine this strategy goes down quite well with the agile hippies. Other vendors such as IBM Rational, have long established board room credibility, and have found ways to sell their often quite expensive and extensive tool sets to CTO s and CIO s. Tools that are often not specifically targeted at agile, but have been lying around on shelves anyway. A company I know just bought around a million dollars worth of tooling on a large vendor s application lifecycle management platform to run their enterprise agile projects. Same ball game, different strategies. Fuzzy But let s be honest, besides these somewhat black-and-white views on the world, it is virtually impossible or at least undesirable to run an agile software development project without tools. If you are trying to organize your rehousing using agile techniques - which I did once -just using post-its on the kitchen door can be enough tooling, but not when you re delivering working software. For instance, there seems to be little debate about using a development environment. Think Visual Studio, Eclipse, IntelliJ. And although I ve seen passionate discussion between developers about which development environment to use, nobody will dispute that you need one. But after that, it gets fuzzier. When discussing agile tooling there is a wide variety of categories to consider. Are you discussing Scrum Boards, Kanban Boards, agile dashboards or Task Boards for instance? Most co-located teams use post-its on the wall, but distributed teams are going to have to rely on something more electronically organized boards. But then what? Mingle? Trello? Speedbird9? Jira Agile? If you re a two man co-located team, post-its on the wall will do fine, and you can easily produce your burn-down chart on a piece of paper or an Excel spread sheet. If you are an international trading company that develops new software around the clock with a highly distributed team of for example requirements people in Singapore and New York, analysts in Stockholm, developers in Poland, and testers in Germany, as I ve seen recently, you might best consider using a complete application lifecycle management platform. At last, some guidelines I do feel sorry if you hoped that this article would present you with the out-of-the-box right tool choice for your project. I am unable to make such recommendation. Your project can and is very likely very different from mine. It might have a different number of teams, a different number of people, different technology, and a different geographical distribution of people. There is no one-size-fits-all agile tool set, as there is no one-size-fits-all agile process. However, I do want to leave you with some practical guidelines when it comes to choosing a specific tool set for your project. So here they are: Start minimal. Always start with the minimal set of tools that will do the work for your current situation. It is always easier to add tools later, then to have to remove tools which you ve been using for half a year just because they didn t add much value. 3M. If you are a co-located team that is not re-building the entire application landscape of a large insurance company, my favorite 3M tooling will do the job nicely: start with post-its on the wall. On my current project we have set up a special room with projector and comfy seats just for doing demo s and retrospectives. Oh, and for doing modeling sessions, because we are using a modeling tool for use cases and domain modeling Enterprise Architect in this particular case. So can you use modeling tools in agile projects? Well, I think you can. If you really need it. I wouldn t recommend setting up a modeling environment such as Enterprise Architect for a six week mobile project, but if you intend to rebuild all administrative systems of let s say an insurance company, a modeling environment is indispensable. And what about bug tracking? We do need tools for that, right? Should we use Basecamp? Or should we use Jira instead? Recently I visited a project where the tester explained that whenever he found a bug on a feature he was testing, he created an issue in Jira. The developer then could pick it up from Jira, and work on it. Sounds reasonable right? It s just that in this project both the tester and the developer are always working on the same feature, and they are literately sitting back-to-back in the office. And what about bug tracking? Management reporting? Tools for unit testing? Integration testing? Continuous integration? Continuous delivery? Are you getting on the continuous delivery train? There are even so many categories of tools, that it s almost impossible to name them all. If you had enough time, you could probably create a short list for each of the categories, but then again, every project if different, so the requirements for tools in each project is likely different too. YAGNI This is where, as often, the YAGNI acronym comes in handy. You Ain t Gonna Need It. You will need to pick the right tools for the right job. If you re just hanging up a picture on the wall, a hammer and nail will probably do the trick, but if you re totally reconstructing your kitchen from the ground up, you will definitively need other heavier equipment. Software development is not much different when it comes to tooling. Track your items. But, always start with tracking the progress of your work items from day one in the project, whether these are user stories, features, smart use cases, chores, bugs or whatever you re doing. This way you at least have data on your project from the start, and you can start counting and measuring at any point in time, which you will want eventually. Yes, Excel. As developers, you might have a big grudge against Microsoft Excel (probably because it s the favorite tool for project managers), but I ve seen many projects that have used a single (not a hard disk full of them) spread sheet successfully to keep track of everything you will need to know in your project. Think of burn-down or burn-up charts, retrospective outcomes, velocity numbers and current work item statuses. Only add when needed. When starting with a minimal set of tools in your project, for some reason, at some point in time, you will realize that some element of your work could be optimized by using a tool. Usually you start to realize this during a sprint s retrospective. Only now figure out what you ve been missing, identify the minimal set of requirements for a-tool-to-add, and then simply choose the cheapest and best fitted product to add to your eco-system. And this tool doesn t have to be the absolute best or most bling-bling magazine voor software development 11

12 GENERAL rich tool you can find on the planet. Just keep it simple. Don t get religious. Many people in the Scrum community feel that it is mandatory to use user stories as their unit of work. However, if you consider the Scrum Guide, the phrase user story does not even appear in it. With tooling, it s not much different. I ve had many discussions with people who feel very religious about one tool or another. Jira is a good example. There s nothing wrong with Jira, but it is by far to be considered mandatory in Scrum projects. Nor is it mandatory to even use an online issue tracking tool. Especially when the whole team is in the same room. Agile tools don t exist. Also, don t let others judge which tools you can or cannot use in your agile project. Or even worse, which tools are agile or are not agile. In my humble opinion, there s no such thing as an agile tool. Tools are either fitted to your project, or are not fitted. I ve been using UML modeling tools and model driven development tools successfully in many agile projects, despite the fact that some zealots think it is not agile to use such tools. No free lunch. There s no such thing as a free lunch. Every tool comes with consequences. Post-its will eventually fall off the wall. Free online dashboard tools are often limited to a certain number of users, of are only available for free for a certain period of time. Frameworks will version. Make sure you realize the consequences. By default, any automated tool you add will create a (vendor) lock-in. To wrap things up, I m sorry that I m unable to give you more concrete tooling recommendations. Every project is different, and agile is a sliding scale. Personally, I consider it wise to start small, and only add tools when the add value, instead of starting with a fully integrated application lifecycle management support eco-system. And at last, always keep in mind that a fool with a tool is still a fool. The same goes for agile fools with tools. Sander Hoogendoorn Sander Hoogendoorn houdt zich in zijn rol als Principal Technology Officer bij Capgemini zich vooral bezig met de innovatie van software development. Sander is erkend global thought leader op het vlak van agile development bij Capgemini. Daarbij is hij onder meer verantwoordelijk voor Capgemini s agile ontwikkelplatform, dat het Accelerated Delivery Platform (ADP) wordt genoemd. Als je voorop wilt lopen in je vakgebied, sluit je je aan bij de SDN community! Als lid van het Software Development Network, kortweg het SDN, ben je op de hoogte van de nieuwste ontwikkelingen. Je maakt deel uit van een netwerk van professionele architecten, designers en ontwikkelaars die elkaar met raad en daad terzijde staan. Je kunt lid worden van het SDN op basis van een bedrijfs- of een persoonlijk lidmaatschap. Het belangrijkste verschil is dat bij een bedrijfslidmaatschap twee of meer personen recht hebben op gratis toegang tot bijeenkomsten en de SDN website, bij een persoonlijk lidmaatschap is dat één persoon. De kosten voor een bedrijfslidmaatschap voor twee personen bedragen 299,- per jaar. Uitbreiding kost 99,- per persoon per jaar. Een persoonlijk lidmaatschap kost 199,- per jaar. Bedragen zijn exclusief 21% BTW. (Bedrijfs)naam : T.a.v. Adres PC/Woonplaats adres Telefoonnr. Personen (indien bedrijfsabonnement minimaal 2) Een lidmaatschap wordt aangegaan voor tenminste één jaar en wordt zonder schriftelijke annulering automatisch met een jaar verlengd op 31 december. Facturering vindt plaats per kalenderjaar of een deel hiervan. Opzeggingen uitsluitend schriftelijk en tenminste zes weken voor het einde van het jaar. Datum Handtekening Verzend dit formulier naar het secretariaat van SDN: Postbus AM Winterswijk of mail naar info@sdn.nl 12 MAGAZINE

13 DELPHI Bob Swart Delphi REST Client Components Apart from the REST Debugger, covered in the previous issue of SDN Magazine, Delphi also contains a number of REST Client components: TRESTClient, TRESTRequest, TREST Response, and TRESTResponseDataSetAdapter, plus four REST authentication components: TSimpleAuthenticator, THTTPBasicAuthenticator, TOAuth1Authenticator, and TOAuth2 - Authenticator. All these new components can be found in the REST Client category of the Tool Palette: REST Twitter Client The example of this article covers the implementation of a REST Twitter Client, connecting to our Twitter account, and being able to send new Tweets. All using the Delphi REST Client components, including one of the Authenticator components (the TOAuith1Authenticator). We start by going to the Twitter API website, were we need to register our application (or at least specify that an application will be accessing the Twitter API). The URL for this is and we must login with our normal Twitter account. Here, we can click on the "Create new App" button to create a new application that will be allowed to communicate with the Twitter API. In the new form, we must specify the details: Fig. 1 The TRESTRequest is the component that makes the actual RESTRequest. It has a Client property (pointing to a TRESTClient) as well as a Response property (pointing to a TRESTResponse component, introduced shortly). Using the TRESTRequest component we can specify the Resource property as well as the Params TRESTRequestParameterList collection. The TRESTResponse component is the one that will receive the response of a connected TRESTRequest component in the Content property. Fig. 2 In our case, I've specified a name of "Delphi Developer Days 2014 Demo" with a description of "Delphi Developer Days 2014 Demo for the RAD Development and REST Client Tools (REST Debugger) session". As website I've used my own URL at although I probably should have used as well. magazine voor software development 13

14 DELPHI Now, click on "Create your Twitter Application", which will give you some more information, like the Access Level, etc. This is the page were we can find some of the initial keys for use with the OAuth authentication to ensure our application has the permission granted to use the Twitter API via REST. Let's take a look at the response. Place a TRESTResponse component (and make sure TRESTRequest Response property points to TRESTResponse now). In de FormCreate, write the following: RESTRequest.Execute; if RESTResponse.GetSimpleValue('oauth_token', LToken)then OAuth1Authenticator1.RequestToken := LToken; if RESTResponse.GetSimpleValue('oauth_token_secret', LToken) then OAuth1Authenticator1.RequestTokenSecret := LToken; Add REST.Authenticator.OAuth.WebForm.Win to the uses clause, and as a result we will see a page where we need to login using out Twitter account, and click on the "Authorize App" button in order to get a PIN code that needs to be used in the next part of our application. Fig. 3 Click on the "Manage API Keys" link to go to a screen with your API Key and API secret key values. You need to copy the API Key and API secret values, and place them in the comments in your Delphi REST Client project, so we can use them shortly. OAUTH In order to be allowed to access the Twitter API using REST, we need to use an OAuth1Authenticator component, so place one on the form. We must set three EndPoint properties to the specific URLs for retrieving the Access Token, the Request Token and for doing the actual Authentication. These properties can be specified in the Object Inspector as follows: AccessTokenEndpoint to RequestTokenEndpoint to AuthenticationEndpoint to Finally, we need to set the CallbackEndpoint property value to oob. Then, set the ConsumerKey and ConsumerSecret property values based on the values from your twitter registered page (the two values you just copied from the web browser). Now, we can place a TRESTClient component on the form (it will automatically connect its Authenticator property to the OAuth1Authentocator1 component). Set the BaseURL to the RequestTokenEndPoint, or twitter.com/oauth/request_token Then, place a TRESTRequest component on the form, and set the Method to mtpost (was mtget) Right-mouse click on RESTRequest and do Execute... This will give Response: HTTP/ OK Fig. 4 To simplify things, I've written the FormCreate event handler that will perform the first two steps, as well as a FormShow that will be used to enter the PIN code (which cannot be copied over the clipboard, so I'm using a InputBox to ask the user to specify the PIN code manually. uses REST.Types, REST.Authenticator.OAuth.WebForm.Win; procedure TFormMain.FormCreate(Sender: TObject); var wv: Tfrm_OAuthWebForm; LToken: String; begin RESTClient1.Authenticator := OAuth1Authenticator1; RESTRequest1.Client := RESTClient1; RESTRequest1.Response := RESTResponse1; OAuth1Authenticator1.RequestTokenEndpoint := 14 MAGAZINE

15 DELPHI ' OAuth1Authenticator1.AuthenticationEndpoint := ' OAuth1Authenticator1.AccessTokenEndpoint := ' OAuth1Authenticator1.CallbackEndpoint := 'oob'; // get your consumer key & secret from OAuth1Authenticator1.ConsumerKey := 'QjCB98tSX25CUpjDXLm3Sw'; OAuth1Authenticator1.ConsumerSecrect := 'J0fs8uaLcRCau8S1ujtG04jtkdOKNVwvSgFQfliTek8'; RESTClient1.BaseURL := OAuth1Authenticator1.Request- TokenEndpoint; RESTRequest1.Execute; if RESTResponse1.GetSimpleValue('oauth_token', LToken) then OAuth1Authenticator1.RequestToken := LToken; if RESTResponse1.GetSimpleValue('oauth_token_secret', LToken) then OAuth1Authenticator1.RequestTokenSecret := LToken; // Get the auth-verifier (PIN must be entered by the user!) wv := Tfrm_OAuthWebForm.Create(self); try wv.showmodalwithurl(oauth1authenticator1.authenticationendpoint + '?oauth_token=' + OAuth1Authenticator1.RequestToken); finally wv.release; end; end; At this point, the OAuth Web Login page will be shown, where we need to log into our Twitter account, and click on the "Authorize App" button in order to get a PIN code. The next step, in the FormShow, will start by getting the PIN code (using the Clipboard, which works on some machines, or the InputBox method), and preparing the REST components so we can make a call to the Tweet API. procedure TFormMain.FormShow(Sender: TObject); const {$J+ Done: Boolean = False; var LToken: String; begin if not Done then begin Done := True; OAuth1Authenticator1.VerifierPIN := InputBox('PIN','PIN:',''); RESTClient1.BaseURL := OAuth1Authenticator1.AccessTokenEndpoint; RESTRequest1.Params.AddItem('oauth_verifier', OAuth1Authenticator1.VerifierPIN, TRESTRequestParameterKind.pkGETorPOST, [TRESTRequestParameterOption.poDoNotEncode]); RESTRequest1.Execute; if RESTResponse1.GetSimpleValue('oauth_token', LToken) then OAuth1Authenticator1.AccessToken := LToken; if RESTResponse1.GetSimpleValue('oauth_token_secret', LToken) then OAuth1Authenticator1.AccessTokenSecret := LToken; /// now we should remove the request-token OAuth1Authenticator1.RequestToken := ''; OAuth1Authenticator1.RequestTokenSecret := ''; OAuth1Authenticator1.CallbackEndpoint := ''; end; end; Note that I'm using a typed constant called Done to ensure that the code inside the FormShow to include the PIN is executed only once, and not for each and every FormShow call. Finally, the code to send an actual tweet is done by sending a status update to the Twitter API, as follows: procedure TFormMain.Button2Click(Sender: TObject); begin RESTClient1.BaseURL := ' RESTRequest1.Resource := '1.1/statuses/update.json'; RESTRequest1.Params.AddItem('status', edtweet.text, TRESTRequestParameterKind.pkGETorPOST); RESTRequest1.Execute; end; Although it may take quite some code, the result is that our custom application can work with the Twitter API and send REST requests using the Delphi REST Client components. Bob Swart Bob Swart is werkzaam in de IT sinds 1983 en heeft daarbij een voorliefde voor (Turbo) Pascal en Delphi. Bob spreekt regelmatig op (internationale) conferenties over Delphi en heeft honderden artikelen geschreven, alsmede zijn eigen Delphi cursusmateriaal voor Delphi trainingen en workshops. Behalve voor het geven van trainingen, is Bob ook beschikbaar voor consultancy, coaching, ontwerp- en bouwwerkzaamheden, of andere ondersteuning op het gebied van software ontwikkeling met Delphi - voor zowel Win32 als.net. Sinds de zomer van 2007 is Bob ook reseller van CodeGear producten zoals Delphi en RAD Studio. Bob Swart Training & Consultancy is gevestigd in Helmond Brandevoort, en beschikt over een eigen trainingsruimte van ruim 42 vierkante meter, inclusief een testlab voor alle mogelijke toepassingen. De voorliefde van Bob voor Pascal en Delphi heeft hij ook tot uiting laten komen in de namen van zijn kinderen Erik Mark Pascal en Natasha Louise Delphine. magazine voor software development 15

16 .NET Piet Amersfoort Async/await en het restaurantmodel Async/await is de belangrijkste uitbreiding van C# in versie 5.0. Deze uitbreiding is toegevoegd om asynchroon programmeren te vereenvoudigen. Het aantal regels code wordt bij toepassing van async/await verminderd en de kans op fouten wordt kleiner. Maar het is ook een extra abstractie laag. Een programmeertaal is per definitie een abstractie die het manipuleren van nullen en enen vereenvoudigd. Maar abstractie op abstractie kan het zicht op wat er werkelijk gebeurt vertroebelen. Hierdoor wordt programmeren gereduceerd tot het toepassen van recepten. Bij problemen is het dan niet meer mogelijk zorgvuldige analyses te maken en uiteindelijk de juiste oplossing te kiezen. Om beter inzicht te krijgen in deze abstracties, zullen we naar de bedrijfsvoering van een restaurant kijken en deze vergelijken met de ontwikkeling van asynchroon programmeren in C#. We kunnen dan iets beter begrijpen op welke wijze async/await problemen voor ons oplost. Simpel voorbeeld van async/await Stel dat we WPF-applicatie willen ontwikkelen die onder andere een window bevat met daarop een invoerveld, een button en een label. Als de gebruiker een priemgetal invoert en op de button klikt, verschijnt op het label de tekst: het ingevoerde getal is een priemgetal. Als er iets anders wordt ingevoerd, verschijnt er een andere tekst. private void Button_Click(object sender, RoutedEventArgs e) { Resultaat.Content = IsPriemWrapper(InputText.Text); private string IsPriemWrapper(string inputtext) { long getal; bool isgetal = long.tryparse( inputtext, out getal); if (isgetal) { return IsPriem(getal)? inputtext + " is een priemgetal" : inputtext + " is niet een priemgetal"; return inputtext + " is niet een getal"; private bool IsPriem(long getal) { for (var i = 2; i < getal; ++i) { if (getal % i == 0) return false; return true; Listing 1: Is een getal een priemgetal? (synchrone versie) Als er kleine getallen worden ingevoerd, dan verschijnt de tekst bijna direct. Bij grote getallen, bijvoorbeeld , duurt de berekening veel langer. Tijdens de berekening kan de gebruiker de applicatie niet meer gebruiken, het scherm is bevroren. Bij Windows desktop applicaties is dit gedrag niet fraai, voor Silverlight en Windows Store Apps is dit gedrag niet acceptabel. De killer feature van versie 5.0 van C# is async/await. Het is aan de taal toegevoegd om asynchroon programmeren voor ontwikkelaars makkelijker te maken. Dus laten we het nieuwe async/await-recept gebruiken: maak van de langzame functie een functie die een Task<TResult> oplevert, in ons geval een Task<string>. Roep deze functie aan met await. Maak de UI-functie async. Nu is de aanroep van de functie asynchroon geworden. Als de gebruiker op de knop heeft geklikt, dan blijft de applicatie reageren. private async void Button_Click( object sender, RoutedEventArgs e) { Resultaat.Content = await IsPriemWrapperAsync( InputText.Text); private Task<string> IsPriemWrapperAsync( string inputtext) { 16 MAGAZINE

17 .NET return Task.Run(() => IsPriemWrapper(inputText)); Listing 2: De aanpassingen om een asynchrone versie van de functie te maken Door deze simpele aanpassing voldoet het programma aan onze eisen en is de code ook te gebruiken in bijvoorbeeld een Windows Store App. Onder de C#-motorkap is veel complexe software verstopt. Het verbergen van complexiteit is in het algemeen een goede zaak. Als we een auto besturen, is het niet noodzakelijk dat we alle details van de werking van de automotor kennen. Het is zelfs aan te raden om tijdens het rijden hierover niet te veel na te denken. Maar, om met Einstein te spreken, maak het simpel, maar niet te simpel. Als onze software complexe scenario s moet ondersteunen, dan is het goed om te weten wat er zich onder de motorkap bevindt. We gaan daarom asynchroon programmeren beschrijven door deze te vergelijken met de bedrijfsvoering van een restaurant. Restaurant 0.0 We hebben de gehele dag achter het toetsenbord doorgebracht en hebben trek in een stukje pizza. We gaan naar Pizzeria Francesco. In deze zaak werkt Francesco en hij is de eigenaar, de ober en de kok. Hij is de enige medewerker. We bestellen een pizza en een flesje wijn Fonterutoli Chianti Classico uit Francesco begint aan de voorbereidingen van de pizza en gaat in de wijnkelder op zoek naar de gevraagde wijn. Hij komt niet meer terug. Na een uur wachten vertrekken we maar. De werkwijze van dit restaurant is te vergelijken met de manier waarop de eerste pc s werkten. Alle opdrachten worden in de gevraagde volgorde uitgevoerd. Als er één of meerdere opdrachten tussen zitten die lang duren, dan kan de gebruiker verder niets meer doen. En als opdrachten zelfs oneindig lang duren en dus geen resultaat opleveren, dan is er geen manier om het programma te stoppen en door te gaan met andere opdrachten. De enige optie is dan de computer uit te zetten, vervolgens weer aan te zetten en nieuwe opdrachten te starten. Ditmaal zonder de opdracht die het probleem heeft veroorzaakt. Restaurant 1.0 We waren niet de enige klanten van het restaurant die problemen hebben gehad. Meerdere klanten zijn boos weggelopen en de zaak was bijna failliet. Francesco heeft daarom een nieuwe manier van werken bedacht. Hij schrijft de opdrachten op kaartjes die hij bundelt met een touwtje. Hij werkt vijf minuten aan het eerste stapeltje met opdrachten, dan gaat de wekker. Hij stopt met zijn werk en pakt het volgende stapeltje en gaat verder met de opdrachten van het nieuwe stapeltje. Na vijf minuten gaat de wekker weer en gaat Francesco verder met de volgende stapel opdrachten. Als hij vijf minuten aan de opdrachten van het laatste stapeltje heeft gewerkt, gaat hij met de opdrachten van de eerste stapel verder. Deze manier van werken is minder efficiënt, omdat Francesco om de vijf minuten van stapel moet wisselen. Als hij een pizza aan het bakken is, moet hij daarmee stoppen en met een andere opdracht verder gaan, bijvoorbeeld het serveren van wijn. Hij moet zich hiervoor omkleden, kokskleding uit, oberkleding aan en verder met de volgende opdracht. Maar het originele probleem is wel opgelost. Als Francesco aan het zoeken is naar een fles wijn die hij moeilijk of niet kan vinden, dan gaan de andere opdrachten door en krijgen uiteindelijk alle gasten eten geserveerd. Dit is de wijze waarop single core Windows pc s werken. Threads zijn setjes instructies die bij elkaar horen, per thread worden de instructies uitgevoerd. Als er meerdere threads zijn aangemaakt, worden deze semi-parallel uitgevoerd. Elke thread krijgt geregeld de tijd om een gedeelte van zijn instructies uit te voeren. In.NET 1.0 is het mogelijk zelf nieuwe threads aan te maken. Deze kunnen worden gestart, waarna de opdrachten semi-parallel worden uitgevoerd. Een nadeel van deze wijze van werken is al genoemd. Het wisselen van thread s kost veel tijd en is daardoor inefficiënt. Er zijn meer nadelen, het aanmaken van nieuwe threads is duur. In termen van het restaurantmodel, het kost Francesco veel tijd en energie om een nieuwe stapel opdrachten aan te maken. Hij moet op zoek naar een nieuwe stapel lege kaartjes, de instructies opschrijven en ze daarna bundelen. Dan moet hij een nieuw stukje touw zoeken en dit door de bundel met opdrachten rijgen. Er is nog een overeenkomst tussen het werk in het restaurant en de meeste Windowsapplicaties. Als Francesco een opdracht moet uitvoeren waarbij er contact is met de gasten, dan zal hij dit als ober moeten doen en niet als kok. Windows Forms en WPF applicaties vereisen het gebruik van STAThreadAttribute. STA is de afkorting van single-threaded apartment. Er mogen wel meerdere threads gebruikt worden in de applicatie, maar er is maar één UI-thread en het is de taak van deze thread de UI aan te passen. Tegen sluitingstijd zijn er nog stapeltjes met opdrachten waaraan gewerkt wordt. Sommige van deze opdrachten kunnen direct gestopt worden, bijvoorbeeld het afbakken van stokbrood voor nieuwe gasten. Andere opdrachten moeten wel worden afgemaakt, bijvoorbeeld de vuile borden in de vaatwasmachine zetten en de machine aanzetten voor het weggaan. Daarom heeft Francesco twee kleuren touwtjes, zwart en rood. Stapels met het zwarte touwtje mogen worden gestopt en stapels met een rood touwtje moeten worden afgemaakt, voordat de zaak kan worden afgesloten. Zo zijn er ook twee soorten threads, background threads en foreground threads. Anders dan de naam suggereert heeft het onderscheid niets te maken met de UI. Het enige verschil is de wijze van stoppen, voor de rest zijn ze identiek. Als een applicatie wordt gestopt, worden de background threads direct gestopt. De foreground threads moeten eerst hun werk afmaken. Call-backs Francesco wacht ook veel, ondanks dat hij het razend druk heeft. Hij stopt het eten in de oven en dan wacht hij de resterende vijf minuten. Daarna gaat hij door met de andere stapeltjes opdrachten. Daarna is weer het stapeltje met het eten in de oven aan de beurt. Dan wacht hij weer vijf minuten en gaat daarna weer door met zijn andere werk. Hij denkt: dat moet anders kunnen. Als hij nu eens twee stapeltjes met opdrachten maakt: één stapeltje met opdrachten tot het eten in de oven gaat en één stapeltje met opdrachten voor als het eten in de oven klaar is. Hij kan dan eerst de voorbereiding uitvoeren, vervolgens het eten in de oven zetten en de stapel met de vervolgopdrachten op een speciale plaats leggen. Nu hoeft hij niet meer nodeloos te wachten. Als het eten in de oven klaar is, gaat hij verder met de klaargelegde stapel vervolgopdrachten..net bevat sinds versie 1.0 classes die het BeginInvoke/EndInvokdepattern implementeren. Dit wordt het Asynchronous Programming Model (APM) genoemd. Als voorbeeld bekijken we de opdracht om in een groot tekstbestand op een netwerklocatie te controleren of er een bepaald woord in voorkomt. Deze opdracht kan synchroon worden uitgevoerd, maar dan moeten we net als Francesco nodeloos wachten totdat alle gegevens zijn verplaatst naar onze pc. Als we deze opdracht asynchroon uitvoeren, kunnen we de controle en de presentatie van het resultaat in een functie vastleggen. Deze functie wordt een call-back-functie genoemd. De functie wordt aangeroepen als de voorgaande activiteiten zijn uitgevoerd. magazine voor software development 17

18 .NET Als we de BeginRead/EndRead methodes van de Stream class gebruiken, kunnen we de BeginRead gebruiken om de informatie te verzamelen en de EndRead om de controle uit te voeren en het resultaat te presenteren. We wachten dan niet actief op het resultaat van de lees- en controleactie, maar we vertellen wat er met het resultaat moet gebeuren en vertrouwen erop dat dit uiteindelijk door een andere thread zal worden uitgevoerd en het resultaat ook zal worden getoond. Bij asynchroon programmeren zijn er drie soorten opdrachten. Opdrachten die voornamelijk door de hoofd processor (CPU) worden uitgevoerd. Deze opdrachten worden CPU bound genoemd en kunnen verder worden verdeeld in kortlopende en langlopende opdrachten. Opdrachten die lang duren worden long running operations genoemd. Het eerste voorbeeld, de bepaling of een getal een priemgetal is, is een voorbeeld van een kortlopende opdracht bij kleine invoerwaarden en een langlopende berekening bij grote waarden. Daarnaast zijn er de opdrachten die hoofdzakelijk niet door de hoofd processor worden uitgevoerd. Deze worden I/O bound opdrachten genoemd. Voorbeelden hiervan zijn lees- en schrijfopdrachten naar de harddisk en netwerkcommunicatie. Elk soort opdracht vereist een andere benadering. Kortlopende opdrachten kunnen beter synchroon worden uitgevoerd, langlopende opdrachten kunnen het beste op een andere thread dan de UI-thread worden uitgevoerd en I/O bound taken kunnen het beste worden gesplitst in deeltaken. Door ons tijdens het programmeren bewust te zijn van dit onderscheid, kunnen we altijd de juiste oplossing kiezen. Voorbereiding Het aanmaken van threads is duur. Franseco moet op zoek naar nieuwe kaartjes, een pen, touw, etc.. En altijd op momenten dat hij zijn tijd wel beter kan gebruiken, want de nieuwe gasten komen binnen, moeten naar hun tafel worden gebracht, de pizza s moeten worden gebakken. Daarom heeft Francesco bedacht dat het handig zou zijn als hij al stapeltjes met kaarten heeft klaarliggen. En hij heeft ook bedacht dat het misschien verstandig zou zijn om de stapeltjes waar hij mee klaar is niet in de vuilnisbak te gooien, maar her te gebruiken. Hij is daarom naar de Makro gegaan en heeft daar een doos opschrijfboekjes gekocht, zodat hij de opdrachten kan vastleggen. In.NET 1.0 is het idee van Francesco geïmplementeerd. Het heet de threadpool. Als de applicatie wordt opgestart, dan worden er al enkele threads aangemaakt. Deze doen nog niets, maar als het nodig is kunnen ze aan het werk. Door de statische methode ThreadPool.QueueUserWorkItem worden ze in de wachtrij gezet om te worden uitgevoerd door de threads. Als laatste heeft Francesco bedacht dat het aantal stapeltjes met opdrachten waaraan hij gelijktijdig werkt, moet worden beperkt. Hij gaat pas aan de slag met een nieuwe stapel als hij een andere stapel met opdrachten heeft afgehandeld. Dit heeft diverse voordelen, onder andere dat als mensen besteld hebben, zij relatief snel eten op tafel krijgen. Aan de stapels met opdrachten die in behandeling zijn wordt relatief vaak gewerkt. Ook de threadpool heeft een beperkte capaciteit. Alle opdrachten worden wel aangenomen (QueUserWorkItem), maar wanneer er daadwerkelijk gestart wordt met de uitvoering van de opdracht, wordt onder andere bepaald door het aantal WorkItems waar al aan wordt gewerkt. Restaurant 2.0 Soms weet Franseco tijdens het voorbereiden van zijn opdrachten nog niet wat er moet gebeuren als het eten uit de oven komt. Dan is het misschien voldoende om het eten uit de oven te halen en te laten weten dat het klaar is. Dan kan hij daarna bepalen wat er met het eten moet gebeuren. In versie 2.0 van.net komt er een tweede asynchroon pattern bij. Dit heet Event-based Asynchronous Pattern (EAP). In plaats van een callback is er een event. Alle methodes die geïnteresseerd zijn in het event kunnen hierop reageren. Daarnaast was er nog het probleem dat de UI door de juiste thread moet worden geüpdatet. Dat werd in.net 2.0 versimpeld door helper-class de SynchronizationContext te implementeren. In termen van het restaurantmodel, de SynchronizationContext onthoudt in welke stapel de klantcontacten zich bevinden, en weet als er informatie beschikbaar komt, hoe deze moet worden doorgespeeld naar de klanten. De SynchronizationContext bezit een Post-methode en accepteert een callback. Restaurant 3.0 Francesco heeft zijn restaurant steeds beter onder controle. Het aantal klanten groeit elk jaar. Ook stijgt elk jaar de productiviteit van Francesco. Door harder te werken kan hij de groei in zijn eentje bijbenen. Echter op een dag is de rek eruit. Aan het eind van de avond heeft hij het zo warm en is hij zo vermoeid, dat hij naar de dokter gaat. Van de dokter moet hij het rustiger aan gaan doen. De dokter stelt voor dat hij een medewerker aanneemt. Op deze wijze kan zijn restaurant doorgroeien. Zijn manier van werken met de stapeltjes opdrachten maakt dit al mogelijk. Taken opsplitsen is nu nog belangrijker. Door deze te splitsen kan het werk worden verdeeld en sneller worden uitgevoerd. Ook de CPU s in onze pc s zijn door de jaren heen steeds sneller geworden. Maar door de processoren sneller te maken, worden deze ook warmer en uiteindelijk worden ze te warm. Dus het sneller maken van de procesoren is gestopt. In plaats daarvan worden nu in een pc meerdere CPU s geplaatst. De noodzaak om het werk eerlijk te verdelen over de CPU s vereist dat bij het ontwikkelen van software opdrachten worden gesplitst, zodat elke CPU kan bijdragen aan het uitvoeren van de opdrachten. Restaurant 4.0 Nu Francesco meerdere medewerkers heeft, is het dus noodzakelijk het werk beter te verdelen. Om dit efficiënter te laten werken, heeft hij een pc aangeschaft. Hierin kan hij de stapeltjes met opdrachten vastleggen en beheren. Hij heeft een abstractie laag toegevoegd. Francesco werkt niet meer met fysieke kaartjes, maar met een elektronische versie van de kaarten. In.NET 4.0 is de Task Pararlel liibrary (TPL) toegevoegd. Dit wordt gezien als een abstractie laag over de al aanwezige threads. Het abstractie moet asynchroon ontwikkelen gemakkelijker maken. Een taak die de TPL ons uit handen neemt, is nadenken over de vraag of we zelf een thread moeten maken of de theadpool-thread moeten gebruiken. De TPL regelt dit voor ons. Waar blijft het eten? Als we voor een theatervoorstelling nog iets willen eten in Restaurant Francesco, dan moeten we op tijd eten geserveerd krijgen en op tijd vertrekken om niets van de voorstelling te missen. Als er vlak voor het vertrek nog geen eten op tafel staat, willen we graag weten hoe lang het nog gaat duren. Als het antwoord is: het kan nog wel even duren dan willen we de mogelijkheid hebben om onze bestelling te annuleren. Als we met een groep mensen in een restaurant uit eten zijn en iedereen heeft zijn eten opgediend gekregen op één persoon na, dan zullen we wachten met eten. Stel nu dat het eten van die persoon is aangebrand en in de vuilnisbak is verdwenen, dan willen we dit wel graag weten. Dan kunnen we het vervolg zelf bepalen. Dat we nog even wachten met eten of dat we alvast beginnen of dat we het eten op tafel verdelen. 18 MAGAZINE

19 .NET Voor de service van restaurants is het essentieel dat bovenstaande processen goed worden ondersteund. In essentie bevatten deze processen de volgende elementen: Prioriteiten (priority) Voortgangsbewaking (progress reporting) Foutafhandeling (exception handling) Beëindigen (cancellation) Vervolgacties of basis van status (callbacks en continuations) Deze elementen worden in de TPL geïmplementeerd. De TPL is een zeer uitgebreide bibliotheek. Helaas ontbreekt hier de ruimte om deze functionaliteit in detail te bespreken. Restaurant 5.0 Francesco is hard aan het werk in zijn restaurant en maakt inmiddels veelvuldig gebruik van het nieuwe systeem. Echter op dagen dat hij niet aanwezig is, wil hij wel dat de zaken doorlopen. De training van medewerkers kost veel tijd. Daarnaast vereist het werken met het systeem veel extra handelingen. Daarom verzucht Francesco weleens: kan het niet wat simpeler? Is het niet mogelijk te werken op een manier die lijkt op de oude eenvoudige manier van werken? We zijn aangekomen bij C# 5.0 met async/await. Aan het voorbeeld van het begin kunnen we zien dat asynchrone code lijkt op de originele synchrone code. Achter de schermen wordt er echter gewerkt met taken uit de TPL, threads uit de threadpool, de synchronisatie context en call-backs. De compiler vertaalt de relatief simpele code in een complexe state machine. Dit gebeurt allemaal om het asynchroon programmeren voor ons zo makkelijk mogelijk te maken. Tot slot Dit artikel is een korte introductie van asynchroon ontwikkelen in C# en async/await. Dit kijkje in de keuken heeft hopelijk tot meer inzicht geleid en smaakt mogelijk naar meer. Ik verwijs om die reden graag naar enkele van de vele boeken waarin veel dieper op de materie wordt ingegaan: Bart de Smet - C# 5.0 Unleashed Joseph Albahari, Ben Albahari - C# 5.0 in a Nutshell Richard Blewett, Andrew Clymer- Pro Asynchronous Programming with.net John Skeet - C# in Depth, Third Edition Piet Amersfoort Piet Amersfoort is zelfstandig consultant op het gebied van bedrijfsautomatisering. Hij is op zoek naar problemen die meer zijn dan een uitdaging. Microsoft-technologieën is één van zijn specialisme. Zijn blog is te vinden op: Microsoft Azure Websites Backup Als je een Microsoft Azure Website hebt gemaakt, dan kun je deze nu ook regelmatig en automatisch laten backuppen. In deze backup routine kun je ook de bijbehorende database of linked resources meenemen. Dit maakt Microsoft Azure websites nog interessanter om te gebruiken. magazine voor software development 19

20 DELPHI Cary Jensen Talking About Frames I like frames, and by frames, I mean instances of the TFrame class first introduced in Delphi 5. I use frames extensively in my applications, and I was very pleased to see frames added to the FireMonkey component library. In this article I want to share with you a couple of techniques that I have been using extensively in my applications. Of course, these techniques apply to frames. I will also share with you an observation about mobile development with Delphi, and will argue that frames solve one of the bigger issues that Delphi mobile developers have been commenting about. But first, let's start with a brief overview of frames. Frames in a Nutshell A frame is a type of module, much like a form or data module. Frames support a design surface for both visual and non-visual components, and in that way are similar to forms. (Data modules also support a design surface, but that design surface is limited to non-visual components.) From a user interface perspective, frames are significantly different from forms. Specifically, forms are intended to be used as a whole, defining a window or dialog box in your application. Frames, by comparison, are more like a fancy panel. Specifically, one or more frames can be placed onto a form, and frames can even be placed into other frames. In this way a frame acts like a compound component. That is, a component that exposes other components, both visual and nonvisual. Unlike a traditional compound component, however, frames permit the objects that have been placed into them to be selected and configured using the Object Inspector from the container in which the frame is placed. For example, I can create a frame that contains a DBGrid and a DataSource. Once I place that frame onto a form, I can still select the DataSource in the frame instance and set its DataSet property. Similarly, from the form on which this frame appears I can easily reach into the frame and change the position of the DBGrid, changing the position in just this one instance of the frame. Permitting the objects that are exposed by a compound component to be configured in this fashion would require custom code, and some of that could get quite complicated. There are two primary benefits of frames. The first is that, under certain circumstances, frames can dramatically reduce the amount of resources that need to be stored in a project. The second, and in most cases the more important benefit, is that frames permit you to visually create objects that can be easily reused and extended. To look at it another way, frames are building blocks for your user interface that can be easily configured at design time. Components that appear on your frame are available in each instance of the frame that you place, and the code defined for the frame is likewise present in each instance. As a result, frames are a powerful tool in an object-based design environment like Delphi, and an excellent source of code reuse. Before I continue, let me acknowledge that it is also possible to make a form appear within another form, and a given form can consist of one or more embedded forms. However, doing so is a strictly runtime operation, and it requires several lines of code, at a minimum. You cannot place one form within another at design time. Furthermore, many of the features of a form, such as its OnClose event handler, are lost when placed on another form. As a result, using a form within a form more or less turns the form into a frame, but without the convenience of design time placement and configuration. Dynamically Created Frames In my brief introduction to frames I emphasized the benefits of the design time use of frames. And while those benefits are very real, they tend to make us forget that frames can play an important role in runtime code. In particular, I often find myself creating frames dynamically at runtime, and the results are something that would be difficult using any other technique. For example, I often have the need to create a calendar-like interface to represent date-related events, such as the daily schedules of work to be performed over the course of a month. In those cases, I create a frame that represents a day, and that frame is designed to display the schedule for a date. At runtime I create one instance of the frame for each day in the month, positioning the frame on the calendar based on its day of the month and day of the week. I might even make each instance of the frame responsible for loading the schedule for the particular date that it represents. Creating a calendar-like interface at design time cannot entirely capture the fluid nature of a calendar. For example, some months have more days than others, and one month (February) occasionally has an extra day, depending on the year. In addition, the first day of the month can potentially land on any day of the week. In other words, the layout of the calendar depends on which month and which year the calendar interface is representing. Dynamically-created frames provide an excellent, object-oriented solution to this interface problem. A calendar is really just one example of dynamic frames. Instead of calendar dates, I might create a frame that represents a team of employees. Since the total number of teams, and the specific employees that constitute each team, may vary from day to day, it is unreasonable to design an interface that displays all teams in advance. Here again, a query to a database can identify the number teams as 20 MAGAZINE

Full text search met Lucene op Azure

Full text search met Lucene op Azure Roy de Boer en Freek Paans Full text search met Lucene op Azure Lucene is een full text search engine, oorspronkelijk geschreven in Java. Het biedt mogelijkheden om grote hoeveelheden tekst efficiënt te

Nadere informatie

MyDHL+ Van Non-Corporate naar Corporate

MyDHL+ Van Non-Corporate naar Corporate MyDHL+ Van Non-Corporate naar Corporate Van Non-Corporate naar Corporate In MyDHL+ is het mogelijk om meerdere gebruikers aan uw set-up toe te voegen. Wanneer er bijvoorbeeld meerdere collega s van dezelfde

Nadere informatie

SAMPLE 11 = + 11 = + + Exploring Combinations of Ten + + = = + + = + = = + = = 11. Step Up. Step Ahead

SAMPLE 11 = + 11 = + + Exploring Combinations of Ten + + = = + + = + = = + = = 11. Step Up. Step Ahead 7.1 Exploring Combinations of Ten Look at these cubes. 2. Color some of the cubes to make three parts. Then write a matching sentence. 10 What addition sentence matches the picture? How else could you

Nadere informatie

2019 SUNEXCHANGE USER GUIDE LAST UPDATED

2019 SUNEXCHANGE USER GUIDE LAST UPDATED 2019 SUNEXCHANGE USER GUIDE LAST UPDATED 0 - -19 1 WELCOME TO SUNEX DISTRIBUTOR PORTAL This user manual will cover all the screens and functions of our site. MAIN SCREEN: Welcome message. 2 LOGIN SCREEN:

Nadere informatie

General info on using shopping carts with Ingenico epayments

General info on using shopping carts with Ingenico epayments Inhoudsopgave 1. Disclaimer 2. What is a PSPID? 3. What is an API user? How is it different from other users? 4. What is an operation code? And should I choose "Authorisation" or "Sale"? 5. What is an

Nadere informatie

MyDHL+ ProView activeren in MyDHL+

MyDHL+ ProView activeren in MyDHL+ MyDHL+ ProView activeren in MyDHL+ ProView activeren in MyDHL+ In MyDHL+ is het mogelijk om van uw zendingen, die op uw accountnummer zijn aangemaakt, de status te zien. Daarnaast is het ook mogelijk om

Nadere informatie

ANGSTSTOORNISSEN EN HYPOCHONDRIE: DIAGNOSTIEK EN BEHANDELING (DUTCH EDITION) FROM BOHN STAFLEU VAN LOGHUM

ANGSTSTOORNISSEN EN HYPOCHONDRIE: DIAGNOSTIEK EN BEHANDELING (DUTCH EDITION) FROM BOHN STAFLEU VAN LOGHUM Read Online and Download Ebook ANGSTSTOORNISSEN EN HYPOCHONDRIE: DIAGNOSTIEK EN BEHANDELING (DUTCH EDITION) FROM BOHN STAFLEU VAN LOGHUM DOWNLOAD EBOOK : ANGSTSTOORNISSEN EN HYPOCHONDRIE: DIAGNOSTIEK STAFLEU

Nadere informatie

!!!! Wild!Peacock!Omslagdoek!! Vertaling!door!Eerlijke!Wol.!! Het!garen!voor!dit!patroon!is!te!verkrijgen!op! Benodigdheden:!!

!!!! Wild!Peacock!Omslagdoek!! Vertaling!door!Eerlijke!Wol.!! Het!garen!voor!dit!patroon!is!te!verkrijgen!op!  Benodigdheden:!! WildPeacockOmslagdoek VertalingdoorEerlijkeWol. Hetgarenvoorditpatroonisteverkrijgenopwww.eerlijkewol.nl Benodigdheden: 4strengenWildPeacockRecycledSilkYarn rondbreinaaldnr8(jekuntnatuurlijkookgewonebreinaaldengebruiken,maar

Nadere informatie

150 ECG-problemen (Dutch Edition)

150 ECG-problemen (Dutch Edition) 150 ECG-problemen (Dutch Edition) John R. Hampton, Piet Machielse Click here if your download doesn"t start automatically 150 ECG-problemen (Dutch Edition) John R. Hampton, Piet Machielse 150 ECG-problemen

Nadere informatie

Introductie in flowcharts

Introductie in flowcharts Introductie in flowcharts Flow Charts Een flow chart kan gebruikt worden om: Processen definieren en analyseren. Een beeld vormen van een proces voor analyse, discussie of communicatie. Het definieren,

Nadere informatie

Hoe met Windows 8 te verbinden met NDI Remote Office (NDIRO) How to connect With Windows 8 to NDI Remote Office (NDIRO

Hoe met Windows 8 te verbinden met NDI Remote Office (NDIRO) How to connect With Windows 8 to NDI Remote Office (NDIRO Handleiding/Manual Hoe met Windows 8 te verbinden met NDI Remote Office (NDIRO) How to connect With Windows 8 to NDI Remote Office (NDIRO Inhoudsopgave / Table of Contents 1 Verbinden met het gebruik van

Nadere informatie

Activant Prophet 21. Prophet 21 Version 12.0 Upgrade Information

Activant Prophet 21. Prophet 21 Version 12.0 Upgrade Information Activant Prophet 21 Prophet 21 Version 12.0 Upgrade Information This class is designed for Customers interested in upgrading to version 12.0 IT staff responsible for the managing of the Prophet 21 system

Nadere informatie

Duurzaam projectmanagement - De nieuwe realiteit van de projectmanager (Dutch Edition)

Duurzaam projectmanagement - De nieuwe realiteit van de projectmanager (Dutch Edition) Duurzaam projectmanagement - De nieuwe realiteit van de projectmanager (Dutch Edition) Ron Schipper Click here if your download doesn"t start automatically Duurzaam projectmanagement - De nieuwe realiteit

Nadere informatie

RECEPTEERKUNDE: PRODUCTZORG EN BEREIDING VAN GENEESMIDDELEN (DUTCH EDITION) FROM BOHN STAFLEU VAN LOGHUM

RECEPTEERKUNDE: PRODUCTZORG EN BEREIDING VAN GENEESMIDDELEN (DUTCH EDITION) FROM BOHN STAFLEU VAN LOGHUM Read Online and Download Ebook RECEPTEERKUNDE: PRODUCTZORG EN BEREIDING VAN GENEESMIDDELEN (DUTCH EDITION) FROM BOHN STAFLEU VAN LOGHUM DOWNLOAD EBOOK : RECEPTEERKUNDE: PRODUCTZORG EN BEREIDING VAN STAFLEU

Nadere informatie

(1) De hoofdfunctie van ons gezelschap is het aanbieden van onderwijs. (2) Ons gezelschap is er om kunsteducatie te verbeteren

(1) De hoofdfunctie van ons gezelschap is het aanbieden van onderwijs. (2) Ons gezelschap is er om kunsteducatie te verbeteren (1) De hoofdfunctie van ons gezelschap is het aanbieden van onderwijs (2) Ons gezelschap is er om kunsteducatie te verbeteren (3) Ons gezelschap helpt gemeenschappen te vormen en te binden (4) De producties

Nadere informatie

Settings for the C100BRS4 MAC Address Spoofing with cable Internet.

Settings for the C100BRS4 MAC Address Spoofing with cable Internet. Settings for the C100BRS4 MAC Address Spoofing with cable Internet. General: Please use the latest firmware for the router. The firmware is available on http://www.conceptronic.net! Use Firmware version

Nadere informatie

Firewall van de Speedtouch 789wl volledig uitschakelen?

Firewall van de Speedtouch 789wl volledig uitschakelen? Firewall van de Speedtouch 789wl volledig uitschakelen? De firewall van de Speedtouch 789 (wl) kan niet volledig uitgeschakeld worden via de Web interface: De firewall blijft namelijk op stateful staan

Nadere informatie

De grondbeginselen der Nederlandsche spelling / Regeling der spelling voor het woordenboek der Nederlandsche taal (Dutch Edition)

De grondbeginselen der Nederlandsche spelling / Regeling der spelling voor het woordenboek der Nederlandsche taal (Dutch Edition) De grondbeginselen der Nederlandsche spelling / Regeling der spelling voor het woordenboek der Nederlandsche taal (Dutch Edition) L. A. te Winkel Click here if your download doesn"t start automatically

Nadere informatie

It s all about the money Group work

It s all about the money Group work It s all about the money Group work Tijdsduur: 45 minuten Kernwoorden: money (geld) coin (munt), banknote (bankbiljet), currency (munteenheid) Herhalings-/uitbreidingswoorden: debate (debat), proposal

Nadere informatie

Preschool Kindergarten

Preschool Kindergarten Preschool Kindergarten Objectives Students will recognize the values of numerals 1 to 10. Students will use objects to solve addition problems with sums from 1 to 10. Materials Needed Large number cards

Nadere informatie

B1 Woordkennis: Spelling

B1 Woordkennis: Spelling B1 Woordkennis: Spelling Bestuderen Inleiding Op B1 niveau gaan we wat meer aandacht schenken aan spelling. Je mag niet meer zoveel fouten maken als op A1 en A2 niveau. We bespreken een aantal belangrijke

Nadere informatie

Borstkanker: Stichting tegen Kanker (Dutch Edition)

Borstkanker: Stichting tegen Kanker (Dutch Edition) Borstkanker: Stichting tegen Kanker (Dutch Edition) Stichting tegen Kanker Click here if your download doesn"t start automatically Borstkanker: Stichting tegen Kanker (Dutch Edition) Stichting tegen Kanker

Nadere informatie

Group work to study a new subject.

Group work to study a new subject. CONTEXT SUBJECT AGE LEVEL AND COUNTRY FEATURE OF GROUP STUDENTS NUMBER MATERIALS AND TOOLS KIND OF GAME DURATION Order of operations 12 13 years 1 ste year of secundary school (technical class) Belgium

Nadere informatie

Comics FILE 4 COMICS BK 2

Comics FILE 4 COMICS BK 2 Comics FILE 4 COMICS BK 2 The funny characters in comic books or animation films can put smiles on people s faces all over the world. Wouldn t it be great to create your own funny character that will give

Nadere informatie

Read this story in English. My personal story

Read this story in English. My personal story My personal story Netherlands 32 Female Primary Topic: SOCIETAL CONTEXT Topics: CHILDHOOD / FAMILY LIFE / RELATIONSHIPS IDENTITY Year: 1990 2010 marriage/co-habitation name/naming court/justice/legal rights

Nadere informatie

Het beheren van mijn Tungsten Network Portal account NL 1 Manage my Tungsten Network Portal account EN 14

Het beheren van mijn Tungsten Network Portal account NL 1 Manage my Tungsten Network Portal account EN 14 QUICK GUIDE C Het beheren van mijn Tungsten Network Portal account NL 1 Manage my Tungsten Network Portal account EN 14 Version 0.9 (June 2014) Per May 2014 OB10 has changed its name to Tungsten Network

Nadere informatie

L.Net s88sd16-n aansluitingen en programmering.

L.Net s88sd16-n aansluitingen en programmering. De L.Net s88sd16-n wordt via één van de L.Net aansluitingen aangesloten op de LocoNet aansluiting van de centrale, bij een Intellibox of Twin-Center is dat de LocoNet-T aansluiting. L.Net s88sd16-n aansluitingen

Nadere informatie

ALGORITMIEK: answers exercise class 7

ALGORITMIEK: answers exercise class 7 Problem 1. See slides 2 4 of lecture 8. Problem 2. See slides 4 6 of lecture 8. ALGORITMIEK: answers exercise class 7 Problem 5. a. Als we twee negatieve (< 0) getallen bij elkaar optellen is het antwoord

Nadere informatie

S e v e n P h o t o s f o r O A S E. K r i j n d e K o n i n g

S e v e n P h o t o s f o r O A S E. K r i j n d e K o n i n g S e v e n P h o t o s f o r O A S E K r i j n d e K o n i n g Even with the most fundamental of truths, we can have big questions. And especially truths that at first sight are concrete, tangible and proven

Nadere informatie

Handleiding Zuludesk Parent

Handleiding Zuludesk Parent Handleiding Zuludesk Parent Handleiding Zuludesk Parent Met Zuludesk Parent kunt u buiten schooltijden de ipad van uw kind beheren. Hieronder vind u een korte handleiding met de mogelijkheden. Gebruik

Nadere informatie

Ontpopping. ORGACOM Thuis in het Museum

Ontpopping. ORGACOM Thuis in het Museum Ontpopping Veel deelnemende bezoekers zijn dit jaar nog maar één keer in het Van Abbemuseum geweest. De vragenlijst van deze mensen hangt Orgacom in een honingraatpatroon. Bezoekers die vaker komen worden

Nadere informatie

Shipment Centre EU Quick Print Client handleiding [NL]

Shipment Centre EU Quick Print Client handleiding [NL] Shipment Centre EU Quick Print Client handleiding [NL] Please scroll down for English. Met de Quick Print Client kunt u printers in Shipment Centre EU configureren. De Quick Print Client kan alleen op

Nadere informatie

EM7680 Firmware Update by OTA

EM7680 Firmware Update by OTA EM7680 Firmware Update by OTA 2 NEDERLANDS/ENGLISH EM7680 Firmware update by OTA Table of contents 1.0 (NL) Introductie... 3 2.0 (NL) Firmware installeren... 3 3.0 (NL) Release notes:... 3 4.0 (NL) Overige

Nadere informatie

Appendix A: List of variables with corresponding questionnaire items (in English) used in chapter 2

Appendix A: List of variables with corresponding questionnaire items (in English) used in chapter 2 167 Appendix A: List of variables with corresponding questionnaire items (in English) used in chapter 2 Task clarity 1. I understand exactly what the task is 2. I understand exactly what is required of

Nadere informatie

Puzzle. Fais ft. Afrojack Niveau 3a Song 6 Lesson A Worksheet. a Lees de omschrijvingen. Zet de Engelse woorden in de puzzel.

Puzzle. Fais ft. Afrojack Niveau 3a Song 6 Lesson A Worksheet. a Lees de omschrijvingen. Zet de Engelse woorden in de puzzel. Puzzle a Lees de omschrijvingen. Zet de Engelse woorden in de puzzel. een beloning voor de winnaar iemand die piano speelt een uitvoering 4 wat je wil gaan doen; voornemens 5 niet dezelfde 6 deze heb je

Nadere informatie

Hoe te verbinden met NDI Remote Office (NDIRO): Apple OS X How to connect to NDI Remote Office (NDIRO): Apple OS X

Hoe te verbinden met NDI Remote Office (NDIRO): Apple OS X How to connect to NDI Remote Office (NDIRO): Apple OS X Handleiding/Manual Hoe te verbinden met (NDIRO): Apple OS X How to connect to (NDIRO): Apple OS X Inhoudsopgave / Table of Contents 1 Verbinden met het gebruik van Apple OS X (Nederlands)... 3 2 Connect

Nadere informatie

ETS 4.1 Beveiliging & ETS app concept

ETS 4.1 Beveiliging & ETS app concept ETS 4.1 Beveiliging & ETS app concept 7 juni 2012 KNX Professionals bijeenkomst Nieuwegein Annemieke van Dorland KNX trainingscentrum ABB Ede (in collaboration with KNX Association) 12/06/12 Folie 1 ETS

Nadere informatie

Registratie- en activeringsproces voor de Factuurstatus Service NL 1 Registration and activation process for the Invoice Status Service EN 10

Registratie- en activeringsproces voor de Factuurstatus Service NL 1 Registration and activation process for the Invoice Status Service EN 10 QUICK GUIDE B Registratie- en activeringsproces voor de Factuurstatus Service NL 1 Registration and activation process for the Invoice Status Service EN 10 Version 0.19 (Oct 2016) Per May 2014 OB10 has

Nadere informatie

Add the standing fingers to get the tens and multiply the closed fingers to get the units.

Add the standing fingers to get the tens and multiply the closed fingers to get the units. Digit work Here's a useful system of finger reckoning from the Middle Ages. To multiply $6 \times 9$, hold up one finger to represent the difference between the five fingers on that hand and the first

Nadere informatie

LONDEN MET 21 GEVARIEERDE STADSWANDELINGEN 480 PAGINAS WAARDEVOLE INFORMATIE RUIM 300 FOTOS KAARTEN EN PLATTEGRONDEN

LONDEN MET 21 GEVARIEERDE STADSWANDELINGEN 480 PAGINAS WAARDEVOLE INFORMATIE RUIM 300 FOTOS KAARTEN EN PLATTEGRONDEN LONDEN MET 21 GEVARIEERDE STADSWANDELINGEN 480 PAGINAS WAARDEVOLE INFORMATIE RUIM 300 FOTOS KAARTEN EN PLATTEGRONDEN LM2GS4PWIR3FKEP-58-WWET11-PDF File Size 6,444 KB 117 Pages 27 Aug, 2016 TABLE OF CONTENT

Nadere informatie

Taco Schallenberg Acorel

Taco Schallenberg Acorel Taco Schallenberg Acorel Inhoudsopgave Introductie Kies een Platform Get to Know the Jargon Strategie Bedrijfsproces Concurrenten User Experience Marketing Over Acorel Introductie THE JARGON THE JARGON

Nadere informatie

Vertaling Engels Gedicht / songteksten

Vertaling Engels Gedicht / songteksten Vertaling Engels Gedicht / songteksten Vertaling door een scholier 1460 woorden 23 januari 2002 5,4 399 keer beoordeeld Vak Engels Songtekst 1 Another day in paradise Artiest: Brandy & Ray J She calls

Nadere informatie

A2 Workshops Grammatica Heden

A2 Workshops Grammatica Heden Bestuderen Present Simple Normaal Hoe maak je de Present Simple? Kijk eerst maar even naar het volgende rijtje. I You He She It We You see see sees sees sees see see They see Je ziet dat het heel eenvoudig

Nadere informatie

voltooid tegenwoordige tijd

voltooid tegenwoordige tijd SirPalsrok @meestergijs It has taken me a while to make this grammar explanation. My life has been quite busy and for that reason I had little time. My week was full of highs and lows. This past weekend

Nadere informatie

Intermax backup exclusion files

Intermax backup exclusion files Intermax backup exclusion files Document type: Referentienummer: Versienummer : Documentatie 1.0 Datum publicatie: Datum laatste wijziging: Auteur: 24-2-2011 24-2-2011 Anton van der Linden Onderwerp: Documentclassificatie:

Nadere informatie

L.Net s88sd16-n aansluitingen en programmering.

L.Net s88sd16-n aansluitingen en programmering. De L.Net s88sd16-n wordt via één van de L.Net aansluitingen aangesloten op de LocoNet aansluiting van de centrale, bij een Intellibox of Twin-Center is dat de LocoNet-T aansluiting. L.Net s88sd16-n aansluitingen

Nadere informatie

Een vrouw, een kind en azijn (Dutch Edition)

Een vrouw, een kind en azijn (Dutch Edition) Een vrouw, een kind en azijn (Dutch Edition) D.J. Peek Click here if your download doesn"t start automatically Een vrouw, een kind en azijn (Dutch Edition) D.J. Peek Een vrouw, een kind en azijn (Dutch

Nadere informatie

EM6250 Firmware update V030507

EM6250 Firmware update V030507 EM6250 Firmware update V030507 EM6250 Firmware update 2 NEDERLANDS/ENGLISH Table of contents 1.0 (NL) Introductie... 3 2.0 (NL) Firmware installeren... 3 3.0 (NL) Release notes:... 5 1.0 (UK) Introduction...

Nadere informatie

Zo werkt het in de apotheek (Basiswerk AG) (Dutch Edition)

Zo werkt het in de apotheek (Basiswerk AG) (Dutch Edition) Zo werkt het in de apotheek (Basiswerk AG) (Dutch Edition) C.R.C. Huizinga-Arp Click here if your download doesn"t start automatically Zo werkt het in de apotheek (Basiswerk AG) (Dutch Edition) C.R.C.

Nadere informatie

Stars FILE 7 STARS BK 2

Stars FILE 7 STARS BK 2 Stars FILE 7 STARS BK 2 Of course you have seen X-Factor, The Voice or Got Talent on TV or via the Internet. What is your favourite act? Do you like the dancing performances or would you rather listen

Nadere informatie

TFS als perfecte tool voor Scrum

TFS als perfecte tool voor Scrum TFS als perfecte tool voor Scrum René van Osnabrugge renevo@delta-n.nl About me René van Osnabrugge Communicate @renevo renevo@delta-n.nl http://osnabrugge.wordpress.com Agenda Wat is Scrum? Wat is ALM

Nadere informatie

Duiding Strafuitvoering (Larcier Duiding) (Dutch Edition) Click here if your download doesn"t start automatically

Duiding Strafuitvoering (Larcier Duiding) (Dutch Edition) Click here if your download doesnt start automatically Duiding Strafuitvoering (Larcier Duiding) (Dutch Edition) Click here if your download doesn"t start automatically Duiding Strafuitvoering (Larcier Duiding) (Dutch Edition) Duiding Strafuitvoering (Larcier

Nadere informatie

Bijlage 2: Informatie met betrekking tot goede praktijkvoorbeelden in Londen, het Verenigd Koninkrijk en Queensland

Bijlage 2: Informatie met betrekking tot goede praktijkvoorbeelden in Londen, het Verenigd Koninkrijk en Queensland Bijlage 2: Informatie met betrekking tot goede praktijkvoorbeelden in Londen, het Verenigd Koninkrijk en Queensland 1. Londen In Londen kunnen gebruikers van een scootmobiel contact opnemen met een dienst

Nadere informatie

ICARUS Illumina E653BK on Windows 8 (upgraded) how to install USB drivers

ICARUS Illumina E653BK on Windows 8 (upgraded) how to install USB drivers ICARUS Illumina E653BK on Windows 8 (upgraded) how to install USB drivers English Instructions Windows 8 out-of-the-box supports the ICARUS Illumina (E653) e-reader. However, when users upgrade their Windows

Nadere informatie

CTI SUITE TSP DETAILS

CTI SUITE TSP DETAILS CTI SUITE TSP DETAILS TAPI allows an application to access telephony services provided by a telecom PABX. In order to implement its access to ETRADEAL, a TAPI interface has been developed by Etrali. As

Nadere informatie

Handleiding Installatie ADS

Handleiding Installatie ADS Handleiding Installatie ADS Versie: 1.0 Versiedatum: 19-03-2014 Inleiding Deze handleiding helpt u met de installatie van Advantage Database Server. Zorg ervoor dat u bij de aanvang van de installatie

Nadere informatie

Archief Voor Kerkelijke Geschiedenis, Inzonderheid Van Nederland, Volume 8... (Romanian Edition)

Archief Voor Kerkelijke Geschiedenis, Inzonderheid Van Nederland, Volume 8... (Romanian Edition) Archief Voor Kerkelijke Geschiedenis, Inzonderheid Van Nederland, Volume 8... (Romanian Edition) Click here if your download doesn"t start automatically Archief Voor Kerkelijke Geschiedenis, Inzonderheid

Nadere informatie

MyDHL+ Uw accountnummer(s) delen

MyDHL+ Uw accountnummer(s) delen MyDHL+ Uw accountnummer(s) delen met anderen Uw accountnummer(s) delen met anderen in MyDHL+ In MyDHL+ is het mogelijk om uw accountnummer(s) te delen met anderen om op uw accountnummer een zending te

Nadere informatie

WWW.EMINENT-ONLINE.COM

WWW.EMINENT-ONLINE.COM WWW.EMINENT-OINE.COM HNDLEIDING USERS MNUL EM1016 HNDLEIDING EM1016 USB NR SERIEEL CONVERTER INHOUDSOPGVE: PGIN 1.0 Introductie.... 2 1.1 Functies en kenmerken.... 2 1.2 Inhoud van de verpakking.... 2

Nadere informatie

Engels op Niveau A2 Workshops Woordkennis 1

Engels op Niveau A2 Workshops Woordkennis 1 A2 Workshops Woordkennis 1 A2 Workshops Woordkennis 1 A2 Woordkennis 1 Bestuderen Hoe leer je 2000 woorden? Als je een nieuwe taal wilt spreken en schrijven, heb je vooral veel nieuwe woorden nodig. Je

Nadere informatie

Een vrouw, een kind en azijn (Dutch Edition)

Een vrouw, een kind en azijn (Dutch Edition) Een vrouw, een kind en azijn (Dutch Edition) D.J. Peek Click here if your download doesn"t start automatically Een vrouw, een kind en azijn (Dutch Edition) D.J. Peek Een vrouw, een kind en azijn (Dutch

Nadere informatie

Cambridge Assessment International Education Cambridge International General Certificate of Secondary Education. Published

Cambridge Assessment International Education Cambridge International General Certificate of Secondary Education. Published Cambridge Assessment International Education Cambridge International General Certificate of Secondary Education DUTCH 055/02 Paper 2 Reading MARK SCHEME Maximum Mark: 45 Published This mark scheme is published

Nadere informatie

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE. Toets Inleiding Kansrekening 1 8 februari 2010

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE. Toets Inleiding Kansrekening 1 8 februari 2010 FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE Toets Inleiding Kansrekening 1 8 februari 2010 Voeg aan het antwoord van een opgave altijd het bewijs, de berekening of de argumentatie toe. Als je een onderdeel

Nadere informatie

Duurzaam projectmanagement - De nieuwe realiteit van de projectmanager (Dutch Edition)

Duurzaam projectmanagement - De nieuwe realiteit van de projectmanager (Dutch Edition) Duurzaam projectmanagement - De nieuwe realiteit van de projectmanager (Dutch Edition) Ron Schipper Click here if your download doesn"t start automatically Duurzaam projectmanagement - De nieuwe realiteit

Nadere informatie

Grammatica uitleg voor de toets van Hoofdstuk 1

Grammatica uitleg voor de toets van Hoofdstuk 1 Grammatica uitleg voor de toets van Hoofdstuk 1 Vraagzinnen: Je kunt in het Engels vraagzinnen maken door vaak het werkwoord vooraan de zin te zetten. Bijv. She is nice. Bijv. I am late. Bijv. They are

Nadere informatie

FOD VOLKSGEZONDHEID, VEILIGHEID VAN DE VOEDSELKETEN EN LEEFMILIEU 25/2/2016. Biocide CLOSED CIRCUIT

FOD VOLKSGEZONDHEID, VEILIGHEID VAN DE VOEDSELKETEN EN LEEFMILIEU 25/2/2016. Biocide CLOSED CIRCUIT 1 25/2/2016 Biocide CLOSED CIRCUIT 2 Regulatory background and scope Biocidal products regulation (EU) nr. 528/2012 (BPR), art. 19 (4): A biocidal product shall not be authorised for making available on

Nadere informatie

Registratie- en activeringsproces voor de Factuurstatus Service NL 1 Registration and activation process for the Invoice Status Service EN 11

Registratie- en activeringsproces voor de Factuurstatus Service NL 1 Registration and activation process for the Invoice Status Service EN 11 QUICK GUIDE B Registratie- en activeringsproces voor de Factuurstatus Service NL 1 Registration and activation process for the Invoice Status Service EN 11 Version 0.14 (July 2015) Per May 2014 OB10 has

Nadere informatie

How to install and use dictionaries on the ICARUS Illumina HD (E652BK)

How to install and use dictionaries on the ICARUS Illumina HD (E652BK) (for Dutch go to page 4) How to install and use dictionaries on the ICARUS Illumina HD (E652BK) The Illumina HD offers dictionary support for StarDict dictionaries.this is a (free) open source dictionary

Nadere informatie

Usage guidelines. About Google Book Search

Usage guidelines. About Google Book Search This is a digital copy of a book that was preserved for generations on library shelves before it was carefully scanned by Google as part of a project to make the world s books discoverable online. It has

Nadere informatie

Over dit boek. Richtlijnen voor gebruik

Over dit boek. Richtlijnen voor gebruik Over dit boek Dit is een digitale kopie van een boek dat al generaties lang op bibliotheekplanken heeft gestaan, maar nu zorgvuldig is gescand door Google. Dat doen we omdat we alle boeken ter wereld online

Nadere informatie

Onder de motorkap van Microsoft Azure Web Sites. Eelco Koster Software architect ORDINA

Onder de motorkap van Microsoft Azure Web Sites. Eelco Koster Software architect ORDINA Onder de motorkap van Microsoft Azure Web Sites Eelco Koster Software architect ORDINA Agenda Introductie Architectuur Project Kudu Azure Resource Manager Doel Dieper inzicht geven in de werking van Azure

Nadere informatie

Buy Me FILE 5 BUY ME BK 2

Buy Me FILE 5 BUY ME BK 2 Buy Me FILE BUY ME BK Can you resist all those incredible products that all seem to be screaming: Buy Me! Every day we see them on TV during the commercial break: the best products in the world. How would

Nadere informatie

Luister alsjeblieft naar een opname als je de vragen beantwoordt of speel de stukken zelf!

Luister alsjeblieft naar een opname als je de vragen beantwoordt of speel de stukken zelf! Martijn Hooning COLLEGE ANALYSE OPDRACHT 1 9 september 2009 Hierbij een paar vragen over twee stukken die we deze week en vorige week hebben besproken: Mondnacht van Schumann, en het eerste deel van het

Nadere informatie

Yes/No (if not you pay an additional EUR 75 fee to be a member in 2020

Yes/No (if not you pay an additional EUR 75 fee to be a member in 2020 Meedoen aan dit evenement? Meld je eenvoudig aan Ben je lid? Ja/Nee Do you want to participate? Please apply Are you a LRCH member? Yes/No (if not you pay an additional EUR 75 fee to be a member in 2020

Nadere informatie

Vergaderen in het Engels

Vergaderen in het Engels Vergaderen in het Engels In dit artikel beschrijven we verschillende situaties die zich kunnen voordoen tijdens een business meeting. Na het doorlopen van deze zinnen zal je genoeg kennis hebben om je

Nadere informatie

Continuous Delivery. Sander Aernouts

Continuous Delivery. Sander Aernouts Continuous Delivery Sander Aernouts Info Support in een notendop Maatwerk softwareontwikkeling van bedrijfskritische kantoorapplicaties Business Intelligence oplossingen Managed IT Services Eigen Kenniscentrum

Nadere informatie

Functioneel Ontwerp / Wireframes:

Functioneel Ontwerp / Wireframes: Functioneel Ontwerp / Wireframes: Het functioneel ontwerp van de ilands applicatie voor op de iphone is gebaseerd op het iphone Human Interface Guidelines handboek geschreven door Apple Inc 2007. Rounded-Rectangle

Nadere informatie

OPEN TRAINING. Onderhandelingen met leveranciers voor aankopers. Zeker stellen dat je goed voorbereid aan de onderhandelingstafel komt.

OPEN TRAINING. Onderhandelingen met leveranciers voor aankopers. Zeker stellen dat je goed voorbereid aan de onderhandelingstafel komt. OPEN TRAINING Onderhandelingen met leveranciers voor aankopers Zeker stellen dat je goed voorbereid aan de onderhandelingstafel komt. Philip Meyers Making sure to come well prepared at the negotiation

Nadere informatie

FAAC DRIVER. Driver install procedure for FAAC boards. Installatieprocedure voor driver voor FAAC-kaarten.

FAAC DRIVER. Driver install procedure for FAAC boards. Installatieprocedure voor driver voor FAAC-kaarten. FAAC DRIVER Driver install procedure for FAAC boards Installatieprocedure voor driver voor FAAC-kaarten www.record-toegangstechniek.nl 1 When a FAAC board (E124 or E145) is connected to the USB port, it

Nadere informatie

Main language Dit is de basiswoordenschat. Deze woorden moeten de leerlingen zowel passief als actief kennen.

Main language Dit is de basiswoordenschat. Deze woorden moeten de leerlingen zowel passief als actief kennen. Lesbrief Les 1.1: On my way Main language Dit is de basiswoordenschat. Deze woorden moeten de leerlingen zowel passief als actief kennen. Nouns: train, tram, bus, car, bike, plane, boat, underground, stop,

Nadere informatie

AlarmShield Interactive Security System Quickstart Guide. Model No. OPG2204

AlarmShield Interactive Security System Quickstart Guide. Model No. OPG2204 AlarmShield Interactive Security System Quickstart Guide Model No. OPG2204 Nederlands Stap 1: Installatie Zorg dat u toegang heeft tot uw router (max. 3 meter afstand). Verbind de Security Shuttle met

Nadere informatie

Davide's Crown Caps Forum

Davide's Crown Caps Forum pagina 1 van 6 Davide's Crown Caps Forum A Forum for Crown Cap Collectors Zoeken Uitgebreid zoeken Zoeken Forumindex Crown Caps Unknown Caps Lettergrootte veranderen vriend Afdrukweergave Gebruikerspaneel

Nadere informatie

Find Neighbor Polygons in a Layer

Find Neighbor Polygons in a Layer Find Neighbor Polygons in a Layer QGIS Tutorials and Tips Author Ujaval Gandhi http://google.com/+ujavalgandhi Translations by Dick Groskamp This work is licensed under a Creative Commons Attribution 4.0

Nadere informatie

Mobile Devices, Applications and Data

Mobile Devices, Applications and Data Mobile Devices, Applications and Data 1 Jits Langedijk Senior Consultant Jits.langedijk@pqr.nl Peter Sterk Solution Architect peter.sterk@pqr.nl Onderwerpen - Rol van Mobile IT in Tomorrow s Workspace

Nadere informatie

MyDHL+ Exportzending aanmaken

MyDHL+ Exportzending aanmaken MyDHL+ Exportzending aanmaken Exportzending aanmaken In MyDHL+ is het aanmaken van een exportzending zo eenvoudig mogelijk gemaakt. De website en deze handleiding zal u stap voor stap erdoorheen leiden.

Nadere informatie

Procedure Reset tv-toestellen:

Procedure Reset tv-toestellen: Procedure Reset tv-toestellen: Volgende procedure is te volgen wanneer er een tv-toestel, op een van de kamers niet meer werkt. TV Re-installation Factory Default Her-installeren van de TV Fabrieksinstellingen

Nadere informatie

Travel Survey Questionnaires

Travel Survey Questionnaires Travel Survey Questionnaires Prot of Rotterdam and TU Delft, 16 June, 2009 Introduction To improve the accessibility to the Rotterdam Port and the efficiency of the public transport systems at the Rotterdam

Nadere informatie

Ius Commune Training Programme Amsterdam Masterclass 15 June 2018

Ius Commune Training Programme Amsterdam Masterclass 15 June 2018 www.iuscommune.eu Dear Ius Commune PhD researchers, You are kindly invited to participate in the Ius Commune Amsterdam Masterclass for PhD researchers, which will take place on Friday, 15 June 2018. This

Nadere informatie

Help je Power BI Analytics project om zeep 6 succesfactoren. Marc Wijnberg Gebruikersdag 2018

Help je Power BI Analytics project om zeep 6 succesfactoren. Marc Wijnberg Gebruikersdag 2018 Help je Power BI Analytics project om zeep 6 succesfactoren Marc Wijnberg Gebruikersdag 2018 20+ jaren ervaring in Business Intelligence BI & Analytics Projectendokter Trainer en Partner Sorsebridge Agile

Nadere informatie

Win a meet and greet with Adam Young from the band Owl City!

Win a meet and greet with Adam Young from the band Owl City! 1 Meet and greet read Lees de tekst. Wat is de prijs die je kunt winnen? early too late on time vroeg te laat op tijd Win a meet and greet with Adam Young from the band Owl City! Do you have a special

Nadere informatie

The first line of the input contains an integer $t \in \mathbb{n}$. This is followed by $t$ lines of text. This text consists of:

The first line of the input contains an integer $t \in \mathbb{n}$. This is followed by $t$ lines of text. This text consists of: Document properties Most word processors show some properties of the text in a document, such as the number of words or the number of letters in that document. Write a program that can determine some of

Nadere informatie

Handleiding Digipass DP310

Handleiding Digipass DP310 Handleiding Digipass DP310 Deze handleiding geeft u uitleg over het activeren en gebruik maken van uw Digipass. Toetsen van de Digipass OK: voor het aan- of uitschakelen van het apparaat of om een handeling

Nadere informatie

Maillijsten voor medewerkers van de Universiteit van Amsterdam

Maillijsten voor medewerkers van de Universiteit van Amsterdam See page 11 for Instruction in English Maillijsten voor medewerkers van de Universiteit van Amsterdam Iedereen met een UvAnetID kan maillijsten aanmaken bij list.uva.nl. Het gebruik van de lijsten van

Nadere informatie

My Inspiration I got my inspiration from a lamp that I already had made 2 years ago. The lamp is the you can see on the right.

My Inspiration I got my inspiration from a lamp that I already had made 2 years ago. The lamp is the you can see on the right. Mijn Inspiratie Ik kreeg het idee om een variant te maken van een lamp die ik al eerder had gemaakt. Bij de lamp die in de onderstaande foto s is afgebeeld kun je het licht dimmen door de lamellen open

Nadere informatie

Tim Akkerman - Head of Mobile

Tim Akkerman - Head of Mobile Tim Akkerman - Head of Mobile Emesa is the largest e-commerce company for searching, comparing and booking travel and leisure packages in the following categories: Holidays - Other accommodations - Hotels

Nadere informatie

3 I always love to do the shopping. A Yes I do! B No! I hate supermarkets. C Sometimes. When my mother lets me buy chocolate.

3 I always love to do the shopping. A Yes I do! B No! I hate supermarkets. C Sometimes. When my mother lets me buy chocolate. 1 Test yourself read a Lees de vragen van de test. Waar gaat deze test over? Flash info 1 In the morning I always make my bed. A Yes. B No. C Sometimes, when I feel like it. 2 When I see an old lady with

Nadere informatie

01/ M-Way. cables

01/ M-Way. cables 01/ 2015 M-Way cables M-WaY Cables There are many ways to connect devices and speakers together but only few will connect you to the music. My Way of connecting is just one of many but proved it self over

Nadere informatie

BISL EEN FRAMEWORK VOOR BUSINESS INFORMATIEMANAGEMENT (DUTCH LANGUAGE) (GERMAN EDITION) (DUTCH EDITION) BY REMKO VAN DER POLS, RALPH DONA

BISL EEN FRAMEWORK VOOR BUSINESS INFORMATIEMANAGEMENT (DUTCH LANGUAGE) (GERMAN EDITION) (DUTCH EDITION) BY REMKO VAN DER POLS, RALPH DONA Read Online and Download Ebook BISL EEN FRAMEWORK VOOR BUSINESS INFORMATIEMANAGEMENT (DUTCH LANGUAGE) (GERMAN EDITION) (DUTCH EDITION) BY REMKO VAN DER POLS, RALPH DONA DOWNLOAD EBOOK : BISL EEN FRAMEWORK

Nadere informatie

MyDHL+ Duties Taxes Paid

MyDHL+ Duties Taxes Paid MyDHL+ Duties Taxes Paid MyDHL+ - verbeterde werkwijze zending aanmaken met service Duties Taxes Paid Intraship In Intraship kiest u voor de Extra service optie Duty Taxes Paid als u wilt dat de transportkosten,

Nadere informatie