34
Jon Shemitz Complicated stuff, quickly. Advanced Delegate s

Jon Shemitz Complicated stuff, quickly

  • Upload
    gianna

  • View
    38

  • Download
    0

Embed Size (px)

DESCRIPTION

Advanced Delegates. Jon Shemitz Complicated stuff, quickly. Advanced Delegates. Delegate syntax Delegate Arcana40% Invocation lists, events, dynamic delegates Delegates vs interfaces Miscellaneous 2.0 enhancements Anonymous Methods15% Delegates as t hread primitives - PowerPoint PPT Presentation

Citation preview

Page 1: Jon Shemitz Complicated stuff, quickly

Jon ShemitzComplicated stuff, quickly.

AdvancedDelegates

Page 2: Jon Shemitz Complicated stuff, quickly

Advanced Delegates

Delegate syntax● Delegate Arcana 40%

Invocation lists, events, dynamic delegatesDelegates vs interfacesMiscellaneous 2.0 enhancements

● Anonymous Methods 15%

Delegates as thread primitives● Asynchronous Invoke 30%● The System Thread Pool 15%

Page 3: Jon Shemitz Complicated stuff, quickly

Invocation Lists

● Delegate class manages an invocation listImplementation changed from 1.1 to 2.0Calling (invoking) a delegate is much faster in 2.0

● Each invocation list is immutableOperators like + and - return new lists

The static methods Delegate.Combine and Delegate.Remove

+= and -= work by replacement

Page 4: Jon Shemitz Complicated stuff, quickly

Delegate Combining

● Value equality, not reference equalityYou do not have to -= the delegate instance you added

Can += Instance.Method now and -= Instance.Method laterYes, these are two separate delegate instances

● List length matters, on Delegate.RemoveSubtract Two from Two, and you have ZeroSubtract Four from Two, and you have Two

● These rules apply to events, too

Page 5: Jon Shemitz Complicated stuff, quickly

Event Syntax

Partial understanding of events is nearly universal!● Simple, field-like events have implicit methods.

An event is never a local variable.Within its class, an event is a delegate -

Outside, an event is the implicit add and remove methods.● Complex, property-like events have no fields.

Explicit add and remove methods.Only those two methods, even within class - not storage.

Page 6: Jon Shemitz Complicated stuff, quickly

Create Delegate

Delegate.CreateDelegatePass a MethodInfo, or a method name

Fewer constraints in 2.0

Calling the delegate is faster than MethodInfo.InvokeGood with dynamically generated methods

Getting dynamically loaded code by name is badSubject to collisionsInterface gets code by contract

Page 7: Jon Shemitz Complicated stuff, quickly

(Code By Contract)

Standard plug-in architecture:● Contract library, used by app and plug-ins● Contains your IPlugin interface● Loading plug-in does GetExportedTypes

Finds types assignment compatible with IPlugin Creates instance, and casts to IPlugin

Page 8: Jon Shemitz Complicated stuff, quickly

Delegate Enhancements in 2.0● New method group syntax

DelegateType DelegateInstance = Instance.Method;Don't have to say new DelegateType(Instance.Method)Just like Delphi ...

Instance.Method specifies an overload method groupValid delegate if one and only one overload in group

● SpeedInterface was 2½ times faster than delegate in 1.xDelegates are ca 5% faster than interfaces in 2.x

Page 9: Jon Shemitz Complicated stuff, quickly

Choose on Semantics

Interface advantagesContracts & dynamically loaded code.● Interfaces are free from versioning

issues and name collisions.● You can control which methods

implement the interface.● An interface reference can give you

access to a whole personality:Other methods in interface, and other interfaces on object.

● Interfaces used to be faster than delegates. Same speed, in 2.0.

Delegate advantagesCallbacks & thread procs.● Less code to create a delegate than

to support an interface - especially when interface supported by a nested class.

● Class may offer a choice of delegate compatible methods; interface reference means the class must explicitly support the interface.

● You can create a delegate to a static or anonymous method. Interface methods are always named instance methods.

Page 10: Jon Shemitz Complicated stuff, quickly

Covarianceclass Base{ public static Derived BaseFn(Base B) { return new Derived(); }}class Derived : Base {}delegate Base BaseFunction(Base B);

●In 1.x, can’t say BaseFunction F = new BaseFunction(Base.BaseFn)

A BaseFunction returns a Base instance.Base.BaseFn returns a Derived instance.

●Can, in 2.xEvery Derived instance is also a Base instance.

Page 11: Jon Shemitz Complicated stuff, quickly

Contravariance class Base { public static void BaseProc(Base B) { } } class Derived : Base { public static void DerivedProc(Derived D) { }

} delegate void BaseMethod(Base B); delegate void DerivedMethod(Derived D);

●A method that takes a base type is compatible with a delegate that takes a derived type:

DerivedMethod BaseD = new DerivedMethod(Base.BaseProc);

Page 12: Jon Shemitz Complicated stuff, quickly

Complicated Names

● Practical effect is that matching is looser● You'll probably only notice covariance and

contravariance when 2.0 code won't compile under 1.x, “even though it's not using generics”

● Don't put effort into telling them apart, or even remembering details of how matching is looserJust remember assignment compatibility

Page 13: Jon Shemitz Complicated stuff, quickly

That's it for the basics

Any questions?

Advanced DelegatesAnonymous MethodsAsynchronous calls

Delegates are asynch primitives

Page 14: Jon Shemitz Complicated stuff, quickly

When a method isn't right

Is there something wrong with named methods?Until 2.0, delegates always referred to named methods.

Usually fine - but there are three problems:● Callbacks are hard to read.

They make you jump around. They add clutter and bloat.● No tie between callback and caller.● Boilerplate - copying local variables to tiny state

objects to support callbacks &c.

Page 15: Jon Shemitz Complicated stuff, quickly

Anonymous Methods● Defining a method just so that you can create a delegate to it

makes your code harder to write and harder to read.● Part of a method has been hoisted into another method.

● C# 2.0 supports anonymous methods, which let you create a delegate to a special statement block, within a method.

● The compiler does the hoisting.● You can't call an anonymous method by mistake.● The compiler does capture better than you do.

(The next screen is about capture.)

Page 16: Jon Shemitz Complicated stuff, quickly

Capture● Anonymous methods can capture parameters and/or local

variables.● Captured variables are implemented as fields in a singleton

instance of a Compiler Generated Class. Captured parameters are copied in, by method prologue,

then only referred to as CGC fields.● Captured variables last as long as the delegate lasts.● Anonymous methods are named methods of the CGC.

Page 17: Jon Shemitz Complicated stuff, quickly

Anonymous Method Syntax

● delegate (optional parametersparameters) {}An anonymous method never has a return type

● Valid in delegate expressions:In assignment;

DelegateType DelegateInstance = delegate(int N) {}; // note the ; after the }

As a parameter to a method; Fn(delegate {})

Event list editing.SomeEvent += delegate(object sender, EventArgs E) {};

Page 18: Jon Shemitz Complicated stuff, quickly

Asynchronous Calls

● You can run any delegate in a thread Available in 1.0 Most people don't know this Syntax is weird, so people “pass” and never return You have to add two null parameters to BeginInvoke

● Functional programmingEndInvoke is like Join, except it returns a typed result.Delegates are asynch primitives:

Easiest way to pass parameters & get thread results.

Page 19: Jon Shemitz Complicated stuff, quickly

Asynchronous Invoke

The best way to pass data to/from a threadFor example: read file to string

Start a read runningDo any other setupEndInvoke when really need resultA cheap, functional thread

Takes a stringReturns a string

May use ThreadPool directly if don't need result.

Page 20: Jon Shemitz Complicated stuff, quickly

Runtime Methods

All delegates have runtime methods● Synchronous Invoke, in caller's thread● Asynchronous BeginInvoke, in ThreadPool thread

Returns IAsyncResult● EndInvoke takes that IAsyncResult

IAsyncResult contains a wait handleMust always call EndInvoke

Page 21: Jon Shemitz Complicated stuff, quickly

EndInvoke

● BeginInvoke starts asynch call● Collect results with .EndInvoke()

Returns same type as delegateWhether void or string or whatever

Can use asynch invoke with void delegate to pass parameters -Cheaper than creating anonymous method that captures parameters.

No casting!● Less overhead than creating new Thread

Less OS work, and less user code

Page 22: Jon Shemitz Complicated stuff, quickly

Control.BeginInvoke

● Two different BeginInvoke methodsBoth return IAsyncResultNever confuse the two!

● Delegate BeginInvoke runs in own threadMust call EndInvoke

● Control.BeginInvoke runs in control's threadCan omit call to EndInvoke

Page 23: Jon Shemitz Complicated stuff, quickly

A Parallelizing Example//foreach (T Datum in Data)// P(Datum); // Process each Datum in the current thread

public class ThreadEach<T>{ public delegate void Processor(T Datum);

public static void Process(Processor P, IEnumerable<T> Data) { List<IAsyncResult> AsyncResults = new List<IAsyncResult>();

// Process each Datum in its own thread foreach (T Datum in Data) AsyncResults.Add(P.BeginInvoke(Datum, null, null));

// Wait for all threads to finish foreach (IAsyncResult Async in AsyncResults) P.EndInvoke(Async); }}

Page 24: Jon Shemitz Complicated stuff, quickly

That was a bad example

What was wrong with that?● Not a good template

Each delegate has own parameter list● Too many threads!

Need to match thread count to processor countUse a Semaphore so only one thread per processorEach thread signs in and signs out

Page 25: Jon Shemitz Complicated stuff, quickly

Those Two Nulls

● The 'extra' parameters to BeginInvokeDon't have to be null

● A delegate called after asynch delegate returnsIn same ThreadPool thread

● A parameter to the callback delegateHard to see point of this - butCan be used for fire and forget

Explicit ThreadPool is better for this

Page 26: Jon Shemitz Complicated stuff, quickly

The system ThreadPool

A high level of control When you manually create a thread

Priority, IsBackground, etc

You don’t need that level of control in every app

Creating a thread is cheaper than creating a processBut it’s not free – there are setup and teardown costs

The ThreadPool reuses threads

Page 27: Jon Shemitz Complicated stuff, quickly

Thread reuse

When you explicitly create a Thread:Thread executes the delegate passed to constructorThread dies when delegate returnsThread is a foreground thread, by default

A TheadPool thread:A background threadDelegate to method of object with delegate field

Executes stored delegateOn return, add the thread to a ready list A new stored delegate when wait handle signals

Page 28: Jon Shemitz Complicated stuff, quickly

Cheaper and Less Code

Defers Thread destruction until process terminationMore importantly:Reusing threads reduces threads a process creates

ThreadPool takes less code, tooJust pass a delegate to a method, and it executesDon't have to Start a Thread

Page 29: Jon Shemitz Complicated stuff, quickly

Explicit ThreadPool

ThreadPool.QueueUserWorkItem static method Executes a WaitCallback delegate

delegate void WaitCallback (object state)

Only one parameter, and it's untypedAnonymous methods can capture state information

(example on the next slide)

Page 30: Jon Shemitz Complicated stuff, quickly

Explicit Exampleprivate static void CaptureExample()

{

string Report = @"Some very big string";

string Filename = @"\A\Drive\Near\You\Report.txt";

ThreadPool.QueueUserWorkItem(delegate {

WriteFile(Filename, Report);

} );

}

Captures Filename and Report from containing method.

Page 31: Jon Shemitz Complicated stuff, quickly

Wait callbacks

The WaitCallback delegate is strangely namedIt's often executed straight-away

The ThreadPool has a different sort of wait callbackThreadPool.RegisterWaitForSingleObject

Takes a WaitOrTimerCallback delegate and a wait handle

More efficient, less reliableOne blocked thread, instead of manyMay want to compile a blocking script

Page 32: Jon Shemitz Complicated stuff, quickly

Thank you

Any Questions?

Page 33: Jon Shemitz Complicated stuff, quickly

Midnight Beach

ContractingConsultingTraining

Page 34: Jon Shemitz Complicated stuff, quickly

Jon Shemitz

Talks fast.

Codes fast, too.