jump to navigation

Thread Synchronization Between Worker Threads April 15, 2021

Posted by codinglifestyle in Architecture, C#, CodeProject, Parallelism.
Tags: , , , ,
add a comment

Many moons ago I wrote the last Windows service I’d ever need. It has a pluggable architecture and today there are over 20 modules doing all manner of business tasks such as sending emails, generating reports, performing automation, etc. Inside each plug-in module is a thread daemon which listens to events to orchestrate the operations of the other supporting module threads. This primarily consists of a thread which provides incoming data (what?), a thread which is the scheduler (when?), and a thread pool of worker threads which process said data (how?).

Recently a new plug-in was created to enforce global trade compliance. A bug crept up in the new worker thread initialization which surprised me because it caused the incoming data queue thread to die even though that code hadn’t changed in years. The reason was that the incoming queue fired the event and therefore it was the thread which executed the delegate (aka function pointer). This function is defined in the thread daemon class which takes care of initializing and starting a worker thread. From an error handling point of view this struck me as less than ideal. So the question was asked:

How do I get the thread daemon to be the thread which executes it’s own management functions which are triggered by events?

This got me thinking about WinForm apps whereby a worker thread must marshal execution of a delegate to the main UI thread to update the UI like changing the status bar. The pattern is to check if an invoke is required (am I the UI thread?) and if not then you use the built in SynchronizationObject to invoke the delegate in the UI thread.

        public delegate void UpdateStatusEvent(string message, params object[] args);

        public void UpdateStatus(string message, params object[] args)
        {
            if (_Status.InvokeRequired)
            {
                UpdateStatusEvent amc = new UpdateStatusEvent(UpdateStatus);
                this.Invoke(amc, new object[] { message, args });
            }
            else
            {
                //Now we are the UI thread we can actually update the status bar
                _LabelStatus.Text = string.Format(message, args);
                _Status.Refresh();
            }
        }

With this pattern in my head I thought I’d be able to implement this quite easily between my background worker threads. How wrong I was and hence this article! WinForms and WPF provide a synchronization context but there isn’t something in the framework you get for free in my case. From what I understand they both implement a classic windows message pump which is used to marshal the execution from the worker thread to the UI thread. This will become important shortly, but suffice it to say after a lot of searching a pre-baked, easy solution wasn’t on offer.

As I continued down this path I searched for ISynchronizeInvoke and IAsyncResult which primarily returned questions and examples of the above pattern. I tried in vein to find an equivalent implementation except for worker threads. Surely it wasn’t that complicated to get an event initiated in Thread A to execute in Thread B? I tried using the SynchronizationContext class but quickly discovered it’s just a base class and didn’t do the work of marshalling the execution from Thread A to Thread B. So while I went through the motions the code still executed in the wrong thread context (so why isn’t this class abstract if you must extend it to get it to work?). BTW, the way I was testing to see which thread was running was to refer to Thread.CurrentThread.ManagedThreadId.

So now I had wasted a lot of time trying to find an easy answer and had to accept some work on my part would be necessary in this scenario. What struck me was the notion of the classic windows pump being crucial for the synchronization context. Basically that it has a message queue running so a thread can enqueue a message and that message then be executed by another thread when it is able. So in the thread daemon I defined a queue and in the OnDoWork created my rudimentary “message pump”.

        private Queue<WaitCallback> _qWorkItems;
        private object _oLock;
      
        protected override void OnDoWork(DoWorkEventArgs e)
        {
            LogSvc.Debug(this, "Running");

            while (!CancellationPending)
            {
                //Critical section
                lock (_oLock)
                {
                    //This is the message pump allowing for the thread synchronization context
                    while (_qWorkItems.Count > 0)
                    {
                        LogSvc.Debug(this, "Dequeue and invoke work item on thread {0}", Thread.CurrentThread.ManagedThreadId);

                        //Dequeue next work item
                        var workItem = _qWorkItems.Dequeue();
                        
                        //Execute work item in thread daemon context
                        workItem.Invoke(null);
                    }

                    //Wait for new work items to process
                    Monitor.Wait(_oLock);
                }
            }
        }

        /// <summary>
        /// Queues a method for execution.  The method executes when the thread daemon is available.
        /// </summary>
        /// <param name="callback">The callback.</param>
        public void QueueWorkItem(WaitCallback callback)
        {
            LogSvc.Debug(this, "Enqueuing work item from event caller thread {0}", Thread.CurrentThread.ManagedThreadId);

            //Critical section
            lock (_oLock)
            {
                _qWorkItems.Enqueue(callback);
                Monitor.Pulse(_oLock);
            }
        }

I started with a Queue<Action> which allowed me to accomplish asynchronous execution. However I wanted to be able to support synchronous execution as well to support getting the return value from the delegate. So I looked at what ThreadPool.EnqueueUserWorkItem used and settled on WaitCallback.

Now we have our thread daemon setup to queue and execute operations in it’s thread context. What we need next is a synchronization context to allow the worker threads to marshal the delegate and data from their thread to the thread daemon thread. We’ll implement both ISynchronizeInvoke and IAsyncResult classes to nicely encapsulate this functionality. This will offer a test to see if an invoke is required and support both asynchronous and synchronous execution of the event delegate.

    /// <summary>
    /// Internally used by ThreadSynchronization to represent asynchronous operations
    /// </summary>
    /// <seealso cref="System.IAsyncResult" />
    class ThreadAsyncResult : IAsyncResult
    {
        /// <summary>
        /// Gets a value that indicates whether the asynchronous operation has completed.
        /// </summary>
        public bool IsCompleted { get; set; }

        /// <summary>
        /// Gets a <see cref="T:System.Threading.WaitHandle" /> that is used to wait for an asynchronous operation to complete.
        /// </summary>
        public WaitHandle AsyncWaitHandle { get; internal set; }

        object _state;
        /// <summary>
        /// Gets a user-defined object that qualifies or contains information about an asynchronous operation.
        /// </summary>
        public object AsyncState
        {
            get
            {
                if (Exception != null)
                {
                    throw Exception;
                }
                return _state;
            }
            internal set
            {
                _state = value;
            }
        }

        /// <summary>
        /// Gets a value that indicates whether the asynchronous operation completed synchronously.
        /// </summary>
        public bool CompletedSynchronously { get { return IsCompleted; } }

        /// <summary>
        /// Gets or sets the exception.
        /// </summary>
        /// <value>
        /// The exception.
        /// </value>
        internal Exception Exception { get; set; }
    }

    /// <summary>
    /// Thread synchronization context to marshal delegate and data to ThreadManager thread
    /// </summary>
    /// <seealso cref="System.ComponentModel.ISynchronizeInvoke" />
    class ThreadSynchronization : ISynchronizeInvoke
    {
        public readonly int _nExecutingContextID = 0;
        private ThreadManager _manager;
        
        /// <summary>
        /// Initializes a new instance of the <see cref="ThreadSynchronization"/> class.
        /// </summary>
        /// <param name="manager">The thread manager object</param>
        public ThreadSynchronization(ThreadManager manager)
        {
            _nExecutingContextID = Thread.CurrentThread.ManagedThreadId;
            _manager             = manager;

            Log.Debug("Synchronization context created for thread {0}", _nExecutingContextID);
        }

        /// <summary>
        /// Gets a value indicating whether the caller must call <see cref="M:System.ComponentModel.ISynchronizeInvoke.Invoke(System.Delegate,System.Object[])" /> when calling an object that implements this interface.
        /// </summary>
        public bool InvokeRequired => Thread.CurrentThread.ManagedThreadId != _nExecutingContextID;

        /// <summary>
        /// Asynchronously executes the delegate on the thread that created this object.
        /// </summary>
        /// <param name="method">A <see cref="T:System.Delegate" /> to a method that takes parameters of the same number and type that are contained in <paramref name="args" />.</param>
        /// <param name="args">An array of type <see cref="T:System.Object" /> to pass as arguments to the given method. This can be <see langword="null" /> if no arguments are needed.</param>
        /// <returns>
        /// An <see cref="T:System.IAsyncResult" /> interface that represents the asynchronous operation started by calling this method.
        /// </returns>
        public IAsyncResult BeginInvoke(Delegate method, object[] args)
        {
            var result                 = new ThreadAsyncResult();
            var manualResetEvent       = new ManualResetEvent(false);
            result.AsyncWaitHandle     = manualResetEvent;

            _manager.QueueWorkItem(delegate
            {
                try
                {
                    //Invoke the delegate and capture the return value
                    result.AsyncState  = method.DynamicInvoke(args);
                }
                catch (Exception ex)
                {
                    Log.Err(ex);
                    //Capture the exception
                    result.Exception   = ex;
                }
                finally
                {
                    //Mark complete
                    result.IsCompleted = true;
                    //Set event for anyone waiting
                    manualResetEvent.Set();
                }
            });

            return result;
        }

        /// <summary>
        /// Waits until the process started by calling <see cref="M:System.ComponentModel.ISynchronizeInvoke.BeginInvoke(System.Delegate,System.Object[])" /> completes, and then returns the value generated by the process.
        /// </summary>
        /// <param name="result">An <see cref="T:System.IAsyncResult" /> interface that represents the asynchronous operation started by calling <see cref="M:System.ComponentModel.ISynchronizeInvoke.BeginInvoke(System.Delegate,System.Object[])" />.</param>
        /// <returns>
        /// An <see cref="T:System.Object" /> that represents the return value generated by the asynchronous operation.
        /// </returns>
        public object EndInvoke(IAsyncResult result)
        {
            //If not complete then wait until done
            if (!result.IsCompleted)
            {
                result.AsyncWaitHandle.WaitOne();
            }

            //The return value of the delegate
            return result.AsyncState;
        }

        /// <summary>
        /// Synchronously executes the delegate on the thread that created this object and marshals the call to the creating thread.
        /// </summary>
        /// <param name="method">A <see cref="T:System.Delegate" /> that contains a method to call, in the context of the thread for the control.</param>
        /// <param name="args">An array of type <see cref="T:System.Object" /> that represents the arguments to pass to the given method. This can be <see langword="null" /> if no arguments are needed.</param>
        /// <returns>
        /// An <see cref="T:System.Object" /> that represents the return value from the delegate being invoked, or <see langword="null" /> if the delegate has no return value.
        /// </returns>
        public object Invoke(Delegate method, object[] args)
        {
            //Get IAsyncResult operation
            var result = BeginInvoke(method, args);
            //Wait for asynchronous operation to complete
            EndInvoke(result);
            //The return value of the delegate
            return result.AsyncState;
        }
    }

So notice that ThreadSynchronization is tied to our thread daemon object which implements QueueWortItem. You could expose access to QueueWorkItem a different way if you wish. So, at long last, we have everything setup so we’re ready to alter the events themselves. These events, located within the thread daemon class, would have executed in another worker thread’s execution context. By instantiating the ThreadSynchronization object we can test if an invoke is required and enqueue the work to execute on the thread daemon thread and even get the return result of the event.

        bool Incoming_Dequeued(object oData)
        {
            bool bReturn = false;

            //If the event is called by a thread other than thread daemon...
            if (Sync.InvokeRequired)
            {
                //Marshal delegate call and data to thread daemon context
                var result = Sync.Invoke(new Func<object, bool>(Incoming_Dequeued), new object[] { oData });
                bReturn    = TypeParser.ParseBool(result, false);

                return bReturn;
            }

            //Execute this code in the context of the thread daemon

            return bReturn;
        }

        void ThreadPool_ThreadComplete(IModuleThread sender, object oResult)
        {
            //If the event is called by a thread other than thread daemon...
            if (Sync.InvokeRequired)
            {
                //Marshal delegate call and data to thread daemon context
                Sync.Invoke(new Action<IModuleThread, object>(ThreadPool_ThreadComplete), new object[] { sender, oResult });
                return;
            }

            //Execute this code in the context of the thread daemon
        }

At last here is the pattern I was looking for all too familiar to anyone who has worked on WinForms or WPF. Now we can easily see if we’re the correct thread and if not do an asynchronous or synchronous invoke of the delegate and data. When invoking it’s easy to use an Action<TIn1, TIn2> or Func<TIn1, Tin2, TOut>, as required, to generate your delegate.

In conclusion, you can see why Microsoft didn’t have a prepackaged solution to this as they couldn’t presume the executing thread would implement a message pump in a strict fashion. They did provide ISynchronizeInvoke which also needs IAsyncResult. Just creating these objects and implementing their interfaces lays bare what you need to do. While I love how it encapsulates this functionality in a familiar manner, it’s not strictly necessary. Really just the implementation of the message pump in our executing thread along with a composite object containing the delegate, data, and a lock would be enough to marshal the required pieces across and signal the thread who fired the event when execution is complete. However, if like me, you are hunting for a best practice implementation I’m very happy with how neatly the above solution turned out in the end.

Advertisement

Tech-ed 2008 November 17, 2008

Posted by codinglifestyle in ASP.NET, C#, IIS, jQuery, Parallelism, Security, SharePoint, Visual Studio 2010.
Tags: , , , , , , , , , , , , , , , , ,
3 comments

Last week I had the opportunity to attend TechEd 2008.  I have compiled a set of notes from the keynote and sessions I attended below.  Most of the information presented at these conferences is not really instructive for addressing today’s problems but talks about future problems and the technologies we will use to address them.  There are some interesting technologies coming down the pipe in the not so distant future and these notes may provide you with enough information to google more information about the topics which interest you.

 

I skipped a lot of older information about the VS2008 release, C# v3.0, and Linq which can all be found here.

 

Keynote

·         Testing Activity Center application

o   Pillar: No more no-repro

o   Generate test cases that tester can click off

o   Bug recording including video, call stack, system information

o   Generate a bug integrated in to Team System

§  Can start up debugger and reproduce tester’s scenario

§  Captures line of code, call stack, everything

·         Code buffering

o   Method shows history of changes (graphically too)

o   Integrates SCC versions in to IDE

·         MVC design pattern

o   Model                   =              data

o   View                     =              web page / UI

o   Controller             =              logic

·         SharePoint Integration

o   Server explorer includes lists, ect

o   Webpart template automatically contains ascx control for design support

o   SharePoint LINQ

o   List Event wizard

§  Auto-generate XML for site def??

·         Performance Profiler

o   Pillar: Leverage multi-core systems

o   See which method is taking time and core utilization

§  Graphically shows core usage including drill down

·         Will help with concurrency, deadlock debugging, ect

VS2008 Service Pack 1 Overview

·         ADO.NET Entity Framework release

o   Very similar to Linq To SQL

o   Generate data model

§  conceptual model static (actual db) model

o   Data Services

§  Data centric abstraction over web services (WFC)

§  Exposes and takes IQueryable so datasets very easy to work with in a LINQ like way

§  Routing lets URI act like a Linq query

·         http://Root/my.svc/Customers/35/FirstName

o   Dynamic Data

§  Given a data model will create aspx accessibility to defined objects

·         Security: all objects off by default but can dynamically access entire data model

·         Allow CRUD access via ASPX templates applied to all objects

o   CRUD = create, read, update, delete

o   Can create individual page for certain object

o   Can customize template to affect all objects

·         Ajax / other enhancements

o   Ajax

§  History Points

·         Addresses problem that users lose ability to hit back button

§  Script combining

·         To improve performance allows to dynamically combine js libraries

o   Improves javascript intellisense

o   Improves web designer performance (bugs/regressions addressed)

C# v4.0

·         History

o   V1 – Managed Code big emphasis

o   V2 – Generics; finished the language

o   V3 – LINQ

·         Pillars

o   Declarative programming: we are moving from “what?” to “how?”

§  LINQ is an example of this

o   Concurrency: Some of the parallelism extensions we will be getting

o   Co-Evolution: VB and C# will more closely evolve together vs. Features hitting languages at different times

o   Static vs. Dynamic Languages: aren’t necessarily a dichotomy

§  Static: C++, C#, VB – anything compiles

§  Dynamic: IronRuby, IronPython, Javascript

·         New keyword: dynamic

o   Call any method of a dynamic object and the compiler won’t complain

§  No intellisense possible

§  Will call during runtime

§  i.e.

·         dynamic calc = GetCalculator();

·         calc.Add(10,20);   //We know nothing about calc object

§  Lots of power to  be explored here

o   Optional Parameters

§  Like in C++ (and apparently VB)

§  Named parameters

·         Can also skip optional parameters

·         Public StreamReader OpenTextFile(string sFile, bool bReadOnly = true, int nBufferSize = 1024);

·         sr = OpenTextFile(“foo.txt”, buffersize:4096);

o   COM Interoperability

§  No more “ref dummy”!

·         Will get: doc.SaveAs(“Test.docx”);  //Winword saveas

·         Versus:   doc.SaveAs(“Test.docx”, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy);

§  Automatic dynamic mapping so less unnecessary casting

§  Interop type embedding

·         No more bringing in PIA

o   Safe Co and Contra-variance

o   Compiler as a service

§  Compiler black box opened up to be used and extended

§  In example created a command window with C#> prompt

·         Was able to define variables, functions, ect like in IronPython

Ajax v4.0

·         Introduction

o   Web app definition

§  Web site is a static collection of pages (such a BBC news)

§  Web application is something which replaces a traditional windows app

o    Traditional Server-Side ASP.NET vs. AJAX

§  Pros

·         Safe: Guaranteed browser compatibility

·         Powerful: All the power of a .NET language in code-behind

§  Cons

·         Response: User must wait for postback

·         Performance: All page content rendered for each interaction

·         Update Panels: Use Wisely

o   An update panel uses sneaky postbacks so while it looks better it is still as bad as traditional server side asp.net

o   Don’t wrap an entire page in an update panel

§  Wrap the smallest region required

§  Use triggers to set what controls will fire a sneaky postback

o   Turn ViewState OFF

§  Down the line this will not be on by default

§  We often send a lot of unnecessary information over the wire in ViewState

·         Ajax Calls (Services)

o   Consider using an Ajax control to update data as needed

o   Calling a web service from javascript is not considered dangerous or bad practice

o   Example

§  Have a datagrid with postback bound to a dropdown list.  Instead of a postback on ddlist use Ajax call

·         Instead of a datagrid use a straight html table

·         Via script we make a call to the web service

·         Use stringbuilder to format return to build up new rows

§  Kinda horrible!  Too much mixing of mark-up and script

·         Client Side Controls

o   Clean way of separating Ajax related script from the web page

o   Allows you to bind to Ajax calls in a template way

o   Example

§  From above we now separate js in to a client side control which is now cleanly referenced on our web page

·         Declarative Client Side Controls

o   “X” in XML stands for extensible; but not often extended!

o   Use XML to bring in namespaces like System and DataView

o   Can define a datagrid purely in html by adding attributes to the

tag in a table

·         Fail over

o   Problem with Ajax is not it is not always supported for reasons of accessibility, search engines, or disabled javascript (mobile devices)

o   Does require double implementation of Ajax and traditional solution but it is an option when needed

·         New features in SP1

o   Back button support!

§  As of VS2008 SP1 Ajax now has back button support

§  ScriptManager property EnableHistory=true and onNavigate event

§  AddHistoryPoint(key,value);

§  AddHistoryPoint(key,value,“Text seen in back button history instead of url”)

§  Process

·         Enable history and add event

·         When page event fires store value (index, ect) with AddHistoryPoint() in provided history cache

·         Use history event to set page back up with value retrieved from HistoryEventArgs

o   Example: set a form to display an item from the last selected index

o   Script Combining

§  Combine scripts for better performance

·         Example showed initial 15sec down to 3

§  Must tell ScriptManager all libraries and it will combine/compress them in to one server call

§  Must explicitly tell which scripts to use – even separate AJAX libraries

·         ScriptReferenceProfiler

o   Free webcontrols which will tell you all the libraries a page uses to make the above less painful

·         Factoids

o   Ajax initiative started to address Outlook Web Access (OWA); a good example of a web application

o   Script Manager is just a way to make sure the page includes the Ajax javascript libraries

§  Ajax script commands prefixed with $

·         $get(“my id”) looks to be handy

§  Can dynamically add event handlers in javascript using Ajax js library

·         $addHandler($get(“dropdownlist1”), “change”, myFunc);

·         Cool “must have” tools

o   Fiddler (www.fiddler2.com)

§  Shows response time, requests/responses, statistics

§  Tip: must place a dot in uri for Fiddler to capture localhost

·         http://localhost./default.aspx

o   Firebug – Firefox extension

 

Visual Studio Tips & Tricks

·         Ppt slides: http://code.msdn.microsoft.com/karenliuteched08

·         A lot more keyboard shortcuts: http://blogs.msdn.com/karenliu/

·         MS and partnered with DevExpress which is offering CodeRush Express for free

o   Required for a lot of the shortcuts and refactoring shown

·         Editing

o   Tools>Options>Editors>C#>Formatting>Set Other Spacing Options>Ignore Spaces

o   Keyboard tricks

§  Ctrl M,O               Toggle collapse all

§  Ctrl M,M              Expand region

§  F12                         Go to definition

§  Shift F12              Final all references

§  Ctrl Shift F8        Jump up Go to definition stack

§  Ctrl [ or ]              Jump between brackets

§  Ctrl Alt = or –      Smart Select

§  Ctrl .                      See smart tag (Implement a missing function, add using statements)

§   

o   Snippets

§  Lots of boilerplate goodies are there.  Really need to start using them

·         Ctor

§  Lots more smart HTML snippets coming

·         Debugging

o   Step OVER properties (r-click at breakpoint to check option)

o   Step into Specific – list of all functions down the chain you can jump to step in to

o   Tools

§  Tinyget – mini stress test

§  Adphang – get memory dump of w3wp

§  Windbg – open dump

·         Loadby SOS mscorwks

o   Need sos.dll for windbg to interpret stack

·         Deployment

o   Web.config transform for release, uat, ect

o   Powerful web deployment publishing options

§  Http, ftp, fpse

§  Msdeploypublish

·         New MS protocol for host supporting includes database, iis settings, access control lists (ACL), ect

·         Free test account at http://labs.discountasp.net/msdeploy

·         Other

o   www.VisualStudioGallery.com  – IDE extensions gallery

§  PowerCommands for VS08

o   VS2008 SDK application

§  Samples tab

·         Click to open sample straight in VS ready to go

Silverlight v2 101

·         XAML

o   A subset of WPF

o   Read-only designer view

§  Must edit  XAML by hand

§  Proper designer on the way

o   Can at least drag XAML text templates for many controls

·         Silverlight Controls

o   Greatly extended in Silverlight v2

§  Visit: www.silverlight.net for a demo

§  Most of what you’d expect in ASP.NET is available in Silverlight

o   Of Note

§  StackPanel

·         Previously on Canvas available requiring static x,y position designation

·         Operates like a panel with z-order

·         Security

o   Lives in a sandbox which can’t be extended for security reasons

o   There are ways to safe access local (isolated) storage, have a file dialog, sockets, cross domain access

·         Nifty

o   Can easily stream media content with one line of XAML

o   Can easily spin any element

Parallelism

·         Introduction

o   Sequential performance has plateaued

o   When we have 30 cores this may lead to dumber cores where we have a situation that today’s software runs slower on tomorrow’s hardware

o   Need  to start thinking about parallelism

§  Understand goals vs. usage

§  Measure existing performance.  VS2010 has tools to do this

§  Tuning Performance

·         Typically we start with sequential programming and add parallelism later

·         VS2010 has Profiler tool for tuning performance

§  Identify opportunities for parallelism

§  Use realistic datasets from the outset; not only on site with the customer

§  Parallelize only when necessary, but PLAN for it as it does introduce race conditions, non-determinism, timing issues, and a slew of other potential bugs

§  Once code is written for parallelism it can scale to any size automatically without any code changes

·         New technologies to help

o   Parallel API

§  Task

·         Like a thread but more optimal with a richer API

o   Has a value for threads which must return a value

§  Accessing the value automatically the same as Thread.Join or Task.Wait

§  ThreadPool

·         Just pass a delegate and let Microsoft worry about the hardware and how to best allocate and spawn threads

·         The ideal number of threads = number of cores

§  TimingBlock class makes it easy to test performance

·         No more: (end time – start time) / 1000

§  Decorate code w/ measurement blocks which appear in Profiler

o   Parallel Extensions

§  First class citizen in VS2010 (SDK today?)

§  Parallel.For and Parallel.ForEach

·         Still need to use critical sections around shared resources inside loop

·         Tip: Best practice is to parallelize the outer for loop only

·         Automatically adds measurement blocks to profiler to see results

§  Parallel.Invoke

§  Parallel extended IEnumerable to perform queries much faster

·         var q = from n in arr.AsParallel() where IsPrime(n) select n;

§  Task group

·         i.e.  For a quick sort instead of using a recursive algorithm use task groups to leverage parallelism with little change to code

o   Debugging – Parallel Stacks

§  Richer API to display tasks or threads and view a holistic mapping of their execution

o   Tools

§  Performance Wizard

·         CPU sampling, timing, ect

§  Profiler

·         Thread Blocking Analysis

o   Shows each thread’s parallel execution revealing race conditions affecting performance

§  Displays information about critical sections in tooltip

§  Can show dependencies for resources/locks across threads

jQuery

·         Ships in future VS but available now

·         Will not be changed by Microsoft but will be supported so we can use it with customers requiring support

·         VS intellisense available from jquery.com

·         Selectors

1.       $(“:text”)             tag          Select all text boxes

2.       $(.required)       class      Select any element with this class tag

3.       $(“#name”)        id            Select with this ID

·         Animations

1.       $(…).Show()

2.       $(…).Hide()

3.       $(…).slideDown()

4.       $(…).slideUp()

5.       $(…).fadeIn()

6.       $(…).fadeOut

7.       Massive open source libraries with hundreds more

§  Plugins.jquery.com

MVC 101

·         MVC

o   Controller (input) pushes to model and view

o   View (UI)

o   Model (logic)

·         An alternative, not replacement, to traditional web forms

·         Easier to test

o   No dependencies on request/response or viewstate as this everything is explicit and therefore testable

·         No server side controls (or designer support), postbacks, or events.

o   Think back to classic ASP

o   What is all this by-hand crap?  XAML (WPF and Silverlight) is only notepad as well

·         Action, instead of event, fires not in View but in the Controller. 

o   The View, aka aspx page, has no code behind.

·         In Controller can define a action and use wizard to create it’s view (web page)

·         ViewUserControl is a collection of html and inline asp which is reusable

IIS v7

·         Modules

o   ASP.NET managed HttpModules can be plugged in directly to IIS v7

§  No more unmanaged ISAPI filters

o   Modules can be managed within IIS v7 Manager

o   Configuration for modules can be exposed through manager

§  Customer WinForm configuration can also be exposed

·         Config

o   No more meta-base

§  All settings exists in central applicationHost.config – similar to a web.config

·         C:\windows\system32\inetsrv\config\schema

§  Can share IIS config for farm scenario

o   www.iis.net contains a configuration pack which allows you to show the config file within the IIS manager

Security

·         Concept of Security Development Lifecycle (SDL)

·         Threat Modelling – package available for formalized  security reviews

o   Talks about prioritizing risks

·         Multi-Pass Review Model

o   1 – Run fuzz and code analysis tools

o   2 – Look for ‘patterns’ in riskier code

o   3 – Deep review of riskiest code

·         Golden rule: What does the bad guy control?

o   What if he controls x & j (resources obtained from user, port, pipeline, compromised file system or database)

§  Char [] f = new char[3];

§  f[3] = 0;                                 bug

§  f[x] = 0;                                 can write a null to anywhere in memory

§  f[x] = y;                                 can write anything anywhere in memory

·         Accepted encryption

o   AES and SHAXXX only

o   Everything else is banned!  So long TripleDES

·         Do not use:  try { } catch (Exception ex) { }

o   Hides bugs and security flaws

o   Catch only exceptions we can handle

IE v8

·         Debug tools included out of the box

o   Hit F12

§  Debug javascript

§  Solve style issues

·         Compatibility – new rendering engine following widely-accepted standard

o   Get prepared for our apps look and feel to break

o   www.msdn.com/iecompat

o   Set meta-tag to tell IE8 to continue to render using v7 engine

·         Accelerators

o   Can develop own accelerators which can highlight a name and pass to a website as a parameter.  Employee staff directory, for example.

Cool Stuff

·         Ctrl-,

o   Quick search feature in 2010

·         Ctrl-.

o   Refactoring: infers using statement.  Generate a new method as your developing

·         Web.config

o   Release version compiles debug/standard web.config and turns off debug, hardens security, replaces config and connection strings

o   Part of the installer

Other Stuff

·         Ribbon support in VS2008 Feature Pack

·         Vista Bridge

o   Wrapper to get access to Vista controls and features

o   TaskDialog and CommandLinks

§  Standard now so will be seen in Win v7

§  Backwards compatible, just extra messages to standard native button

o   Restart/Recovery API

§  Get notified of a reboot

§  Register delegate called in separate thread when app crashes/reboots

§  OS will run app with a command line argument you catch to load saved info

o   Power Management

§  Get notified about all power related info, low battery, ect

Biz Stuff

·         StepUp Program

o   Allows customers to upgrade current SKU

§  i.e. VS Pro to Team Foundation Server

§  30% discount until June 2009

Multi-threaded WebService: “Unable to connect to remote server” April 24, 2007

Posted by codinglifestyle in ASP.NET, IIS, Parallelism.
Tags: , , , , ,
2 comments

You know you’ve made it in to hackerdom when 4000 ports just isn’t enough.  I need more power!

 

I have a webservice which spawns, potentially thousands, of threads.  These in turn are calling a webservice in SharePoint to perform a real-time query (or else we could make a single call to the search service which relies on the index being up-to-date).  I did think to include a throttle which would restrict the total number of threads spawned across all calls to the webmethod.  However, even with this number safely at 100 threads I didn’t account for TCP/IP’s default settings keeping the port alive 4 minutes.  It didn’t take long to put around 4000 ports in a TIME_WAIT state.  When my webservice would make a call to the SharePoint webservice this would result in a System.Net.WebException:

 

“Unable to connect to remote server” with an inner exception of:

 

“Only one usage of each socket address (protocol/network address/port) is normally permitted”

 

The solution was simple enough and is common across a number of greedy applications.  TCP/IP allows us to up the ante by changing a few parameters in the registry.  This allows you to adjust the delay before a port is available again.  In addition you may increase the number of ports at your disposal by nearly 60,000.  If this isn’t enough, maybe a design change is in order!

 

Here’s how you do it:

 

The product handles heavy query volumes more efficiently if the following TCP/IP parameters are set in the Windows® registry:

1.       Start the registry editor:

a.       Click the Windows Start button.

b.       Click Run.

c.       Type regedit in field provided.

d.       Click OK

2.       Use the following directory path to navigate to the registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

3.       In the right pane of the registry editor, look for the TcpTimedWaitDelay value name. If it is not there, add it by selecting Edit > New > DWORD Value from the menu bar. Type the value name TcpTimedWaitDelay in the name box that appears with the flashing cursor.

Note: If you do not see the a flashing cursor and New Value # inside the box, right-click inside the right panel and select Rename from the menu, then type the value name TcpTimedWaitDelay in the name box.

4.       Double-click inside the right pane again to set the value of TcpTimedWaitDelay. Select Decimal as the Base, and enter 30 in the Value data field.

5.       In the right pane of the registry editor, look for the MaxUserPort value name. If it is not there, add it by selecting Edit > New > DWORD Value from the menu bar. Type the value name MaxUserPort in the name box that appears with the flashing cursor.

Note: If you do not see the a flashing cursor and New Value # inside the box, right-click inside the right panel and select Rename from the menu, then type the value name TcpTimedWaitDelay in the name box.

6.       Double-click inside the right pane again to set the value of MaxUserPort. Select Decimal as the Base, and enter 65534 in the Value data field.

7.       You must restart Windows for these settings to take effect

 

Reference: http://blogs.msdn.com/dgorti/archive/2005/09/18/470766.aspx

 

 

 

Update! 

 

After issuing the above changes were made and the customer finally rebooted the server I ran in to an new, exciting System.Net.WebException:

 

The underlying connection was closed: An unexpected error occurred on a send.” with a status of: SendFailure

 

Searching for this exception lead me to exactly the information I was looking for.  Let’s close down those ports as soon as we are done with them.  I have no desire to use up thousands of ports and wear the hacker crown.  We can do this by changing the keep alive state of our web request to false.  Funny that this isn’t by default false for a webservice nor is it a public member to set like the timeout.  We have two choices, the high road and the low road.  First the low road:

We will alter generated proxy class directly; meaning your fix may be lost if you update your web reference.  In the GetWebRequest function the KeepAlive property must be set to false. This can be accomplished by following these steps:

  • Add a Web Reference using the normal way (if you haven’t already added one ofcourse).
  • Make sure Show All Files menu item is enable in the Project menu.
  • In the Solution Explorer window, navigate to:
    • Web References
        • Reference.map
          • Reference.cs (or .vb)
  • Open the Reference.cs file and add following code in the webservice proxy class:
    • protected override System.Net.WebRequest GetWebRequest(Uri uri)

      {

      System.Net.HttpWebRequest webRequest =

                      (System.Net.HttpWebRequest)base.GetWebRequest(uri);

       

            webRequest.KeepAlive       = false;

            webRequest.ProtocolVersion = HttpVersion.Version10;

       

            return webRequest;

      }

       

       

The high road, or proper way of doing this, is to subclass our webservice such that we don’t touch the auto-generated proxy class.  Here is a sample: 

 

using System;
using System.Net;
using System.Reflection;

// Web service reference entered in wizard was “MyWebService.MyWebServiceWse”
using MyProject.MyWebService;

namespace MyProject
{
 public class MySubClassedWebService : MyWebServiceWse
 {
  private static PropertyInfo requestPropertyInfo = null;

  public MySubClassedWebService(){}

  protected override System.Net.WebRequest GetWebRequest(Uri uri)
  {
   WebRequest request = base.GetWebRequest(uri);

   // Retrieve property info and store it in a static member for optimizing future use
   if (requestPropertyInfo==null)
    requestPropertyInfo = request.GetType().GetProperty(“Request”);

   // Retrieve underlying web request
   HttpWebRequest webRequest = (HttpWebRequest)requestPropertyInfo.GetValue(request, null);

   // Setting KeepAlive
   webRequest.KeepAlive = false;
   // Setting protocol version
   webRequest.ProtocolVersion = HttpVersion.Version10;
   return request;
  }
 }
}

 

 

 

Reference: http://weblogs.asp.net/jan/archive/2004/01/28/63771.aspx