Sunday 29 November 2009

Solving Delegate Variance

Post redacted. It turns out I was making a meal out of something silly - converting from (for example) an EventHandler delegate-instance to a MouseEventHandler delegate instance.

I did it the hard way; Barry Kelly has the right idea (see comments). I bow to greater wisdom.

Wednesday 25 November 2009

Does it work on MonoTouch? And more crazy constructors…

A double-feature ;-p The first didn’t seem to warrant a blog entry by itself, but I found if fascinating; as if interface constructors aren’t enough… when is “new T() == null” – and I’m not accepting Nullable<T> ! Ayende Rahien posts a fascinating “feature” of .NET – well worth a read. Caution – it might make you feel dirty…

But what I really came here for; MonoTouch… I had anMonoTouch box e-mail earlier from somebody asking if protobuf-net would work on MonoTouch. My answer there is simple: I have no idea! I’d love to be able to give a better answer, but even the free evaluation edition needs a Mac. protobuf-net is a voluntary and revenue-free project, and I simply can’t justify buying a Mac to investigate.

I’m pretty sure that the “Reflection.Emit” code would have to go, but that is already the case for Compact Framework etc. I honestly don’t know about the rest of the reflection and/or optimisations. I might be able to offer guidance if anybody wants to try to get it working on MonoTouch (unless you want to lend me your Mac, iPhone and MonoTouch license for a while…).

Tuesday 17 November 2009

LINQ Query Syntax – a whistlestop

Based on some feedback (both comments and e-mail) to my last entry, it seems obvious to me that a number of readers aren’t familiar with the way that LINQ maps query syntax to real code.

So I thought I’d offer a very brief taster. For real detail here, good resources include:

So hang on – I said this was a whistlestop, but this isn’t a short blog. You see, I never said this was a simple area. Go read one of the above and hopefully it will make more sense… but we’ll muddle on and see if anything sticks…

What is LINQ query syntax?

At the spec level, it isn’t quite what many people think it is… it knows nothing about what it is doing. It doesn’t have any knowledge of “IEnumerable”, “IQueryable”, etc – it is just a set of rules that map keywords like “from”, “select”, “join” etc into instance-style method calls using lambdas.

The rules for this are… “complicated”, for example:

A query expression with a second from clause followed by something other than a select clause:

from x1 in e1
from x2 in e2

is translated into

from * in ( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => new { x1 , x2 } )

Don’t worry – you don’t usually need the details; I didn’t use the spec to write my custom “SelectMany”, for example. A bit of guesswork, and a quick check against the standard “Enumerable.SelectMany” got me going.

So what does my code look like?

As always, reflector will be useful (if you crank down the optimisations, as discussed here), but let's pick apart the example from yesterday:

image

The first “from” is largely inert; perhaps the most important thing it does is propose a name (and optionally type) for the first variable* “path”.

*=I’m using the term loosely.

The additional “from” statements are more interesting. These do a “SelectMany” (see quote above), but in order to keep “path” in scope, it uses the overload that accepts two lambdas; one to select the data (“File.OpenRead(path)” etc), and another to create a new type representing both “path” and the new data. Not necessarily very obvious, but something like:

image

(The “x1” / “x2” identifiers are introduced by the compiler)

So where do the methods come from?

Here’s the interesting thing: the LINQ spec doesn’t care! It could be an instance Select (etc) method declared on the actual type that happens to be “in play”; it could be a custom extension method provided after-the-fact. The actual method is resolved by regular C# member resolution rules. A few interesting examples of alternative implementations include:

At one point I had an F#-style async implementation using LINQ query syntax, but… well, I wasn’t very happy with it – sometimes you can push too hard ;-p

Or (as in the example with IDisposable) you can just offer some new code for specific cases. As long as the C# compiler can resolve a preferred implementation, you’re in business.

Summary

  • LINQ = translation to instance-style method calls using lambdas
  • You can write your own
  • It isn’t at all limited to things like IEnumerable
  • Since it uses lambdas, it can be delegate-based or Expression-based

Go crazy; try your own query syntax implementation today ;-p

Monday 16 November 2009

SelectMany; combining IDisposable and LINQ

Something that often trips me up in LINQ is that you frequently have to break out of the query syntax simply to add a few “using” blocks. It is important to keep the “using” to ensure that resources are released ASAP, but the regular LINQ query syntax doesn’t let you do this. For example (and I realise there are better ways of doing this – it is for illustration only):

image

Trying to write this (or something like this) in LINQ query syntax (or fluent syntax) just gets ugly.

If only there were a way to convince it to run the “Dispose()” for us as part of the query! A “let” looks promising, but this won’t do anything special in the error case. But there is a pattern (other than just “using”) that lets us conveniently run code at the end of something… “foreach”. And both query-syntax and fluent-syntax already play nicely with extra “foreach” blocks – it falls (loosely) into “SelectMany”.

Thoughts; we could write an extension method that turns “IDisposable” into “IEnumerable”:

image

image

This is a step in the right direction – but those hanging “Using” blocks bother me - and the disposable object isn't quite inside the iterator - there are probably some corner-cases that would lead to items not getting disposed. But LINQ syntax is purely a query comprehension syntax; we aren’t limited to the current conventions – we can write an alternative version of “SelectMany”:

image

(hey, I never said SelectMany was pretty!)

This allows a much more interesting use:

image

This now does everything we want, without any ugly – our disposable items get disposed, and we can write complex chained queries.

I still haven’t decided whether this is too “out there” – i.e. whether it adds more benefit than it does confusion. All thoughts appreciated!

Sunday 15 November 2009

State Assassins with experience of Reporting Services

No, this isn’t one of the more unlikely job listings on careers – instead, a bit of work from last week that I found pretty interesting.

images[1]I was essentially adding some consultancy input to an unfamiliar codebase; the problem was that the site would be running very smoothly, then page-times would go crazy for a while, and then suddenly go back to normal.

It turned out (after putting state into SQL-Server for analysis) that some of the state records were unexpectedly large. Damagingly huge. So what were they? After all, the app only used state to store one tiny innocent object…

One advantage of using a database for state is that you can get the data back out, and it turns out that it isn’t too hard to reverse a BLOB back into the state objects (it helped that stackoverflow had half the answer already).

The cuplrit? You might guess (from the post title): reporting services and the web-forms report viewer control. As soon as a user viewed a report, it was using state to cache the data – which might work great for small reports, but if the report is large it gets… fun.

Perhaps a design failing in ASP.NET state; once a large object is in state, it goes up and down the wire (between the web-server and the state storage) on every state-enabled request for that user, even when no longer using that data. So if they used the report 10 minutes ago, and are now just looking at nice slim tidy pages, they are still dragging a huge state object over the network all the time, potentially crippling the site for lots of other users.

If the page had been highly AJAX-enabled it could have been much worse. And the reason the problem ended so abruptly? My reasoning is that the user in question (who is harming the site through no fault of their own) got bored of sluggish responses and did something else for a while.

Learning points:

  • Even if you aren’t using SQL Server for state normally, it makes analysis much easier as a temporary swap-out
  • Watch out for web-controls (especially reports) that might (ab)use state
  • You can decipher a regular state BLOB – it isn’t tricky (I’ll update that SO question with an example if anyone is interested)
  • Consider partitioning your app, or disabling state in some scenarios
  • We aware of how much data your reports are dragging around with them

Tuesday 10 November 2009

Controlling WCF / protobuf-net at the Endpoint

protobuf-net has had WCF hooks for a long time, but (to be frank) they’ve been a tad…. flakey.

Firstly, if you use “mex” generated proxy classes, it has a habit of discarding key metadata (the “Order” of the [DataMember]). This can be resolved either by using a shared DTO assembly, or by using fixups in the partial class – but…

Secondly, even if you have a shared DTO assembly, if you use the standard “add service reference” (or svcutil.exe), it duplicates the service-contract interface, and it drops the [ProtoBehavior] marker. Again, you can get around this by using the WCF channel directly or subclassing ClientBase<T> – but it would be nice if this wasn’t necessary.

Additionally, it would be very nice if the protobuf-net aspect was configurable (app.config/web.config); allowing greater reuse, and allowing parallel endpoints (with/without protobuf-net, to support vanilla and protobuf-net aware clients).

The community to the rescue

Step up Scott Prugh, who an embarrassingly long time ago very kindly supplied me with all the cogs to make this happen. Apologies for the delay, but things have been hectic and when I tried to test it my WCF brain-cells were switched off (in short: I borked my tests, couldn’t get it working, and had to shelve it for a while).

So what’s the shiny? Simply: rather than decorating your operations with [ProtoBehavior], we can apply it in the configuration instead, by adding an endpoint-behavior that references a custom WCF extension (which we must also add). This sounds worse than it is'; inside “system.ServiceModel” (in your app.config/web.config, this means adding a few lines of boilerplate:

image

And then to both client and server, we simply specify the endpoint configuration:

image

(in more complex scenarios you might want to add the custom extension to your existing endpoint configuration).

What’s the catch?

In the most part, that’s it. WCF will use protobuf-net for any suitable objects (data-contracts etc). Note that this is a coarser brush than the per-operation control, though (you could always split the interface into different endpoints, of course).

Also, protobuf-net does have some subtle differences (especially regarding empty objects), so run your unit tests etc.

Note that it only works on the full-fat WCF; it won’t help Silverlight etc, since it lacks the extension features – but that isn’t new here.

Finally, the resolver in WCF is a pain, and AFAIK wants the full assembly details including version number; so one more thing to maintain when you get new versions. If anyone knows how to get around this?

plzsendtehcodez

A minimal (but working) example is in the repo (client, server). This uses a shared DTO assembly (to avoid the need for fixups) and is based on the WCF project template. I’ll try to go back and retrofit the Northwind example shortly, and perhaps include the WCF samples in a simple download.

Monday 2 November 2009

Highly Polished Software

Slippery surface
No, not what you think...

Is it just me that dreads finding that the office cleaners have come around? Re-attaching jostled cables and re-adjusting monitor heights is one (annoying) thing - but how much polish does a desk really need? I can barely touch my laptop without it sliding over the desk - so you can imagine what my "freak keyboard" is like.

Coffee spill
Looks like I'm going to have to spill copious amounts of coffee just to make the desk usable again. Sigh.