An aggregation of all the Rock Solid Knowledge Blogs
Its been a while coming, but there it is no possible to use LINQ against NHibernate..I think its a shame that MS didn’t get behind the Hibernate family when they first created LINQ as its a marriage made in heaven, combining a mature ORM with a language integrated query. Rather than spending all that time ( and still ) on trying to create their own ORM.
I’ve yet to try out the integration, but hopefully will be over the next few weeks…
.NET 4 Tasks offers much better support for task cancellation, unlike QueueUserWorkItem tasks can be cancelled before commencing, and the Task library offers a standard way for running tasks to detect and report cancellation. I recently recorded a screencast that demonstrated the new Task API including the cancellation support. This blog post isn’t so much about the cancellation mechanics but some guidance on how best to use it if you don’t want to change the throughput of your task.
Below is some code that calculates pi, it is expecting to be run inside a task and is supporting the notion of cancellation.
private static double AbortableCalculatePi()
{
double pi = 1;
double multiplier = -1;
const int N_ITERATIONS = 500000000;
for (int nIter = 3; nIter < N_ITERATIONS; nIter += 2)
{
if (Task.Current.IsCancellationRequested)
{
Task.Current.AcknowledgeCancellation();
return 0.0;
}
pi += (1.0 / (double)nIter) * multiplier;
multiplier *= -1;
}
return pi * 4.0;
}
So all well and good until you benchmark it and compare it to the version with no cancellation support and it runs almost twice as slow. The reason being that the cost of detecting cancellation is high in relation to the work being done. The important aspect to cancellation is being able to respond in a meaningful time for the client, at present we are being way over aggressive in checking.
One option would be to only check every N iterations..
private static double BetterAbortableCalculatePi()
{
double pi = 1;
double multiplier = -1;
const int N_ITERATIONS = 500000000;
for (int nIter = 3; nIter < N_ITERATIONS; nIter += 2)
{
if ((nIter - 3) % 100000 == 0)
{
if (Task.Current.IsCancellationRequested)
{
Task.Current.AcknowledgeCancellation();
return 0.0;
}
}
pi += (1.0 / (double)nIter) * multiplier;
multiplier *= -1;
}
return pi * 4.0;
}
This took a third less time than the previous more aggressive version. However the if block’s effect on the pipeline and the additional maths is still an additional cost over the version that had no cancellation support.
So a third approach is called for this time refactoring the algorithm to use two loops instead of one, were the check for cancellation is done once per iteration of the outerloop, this results in little additional cost.
private static double OptimisedAbortableCalculatePi()
{
double pi = 1;
double multiplier = -1;
const int N_ITERATIONS = 500000000 / 2;
const int OUTER_ITERATIONS = 10000;
const int INNER_ITERATIONS = N_ITERATIONS / OUTER_ITERATIONS;
int i = 3;
for (int outerIndex = 0; outerIndex < OUTER_ITERATIONS; outerIndex++)
{
for (int nIter = 0; nIter < INNER_ITERATIONS; nIter++)
{
pi += (1.0 / i) * multiplier;
multiplier *= -1;
i += 2;
}
if (Task.Current.IsCancellationRequested)
{
Task.Current.AcknowledgeCancellation();
return 0.0;
}
}
return pi * 4.0;
}
Here are the timings are got from the various approaches
NoAbortableCalculatePi = 3.14159264958921 took
00:00:03.7357873
AbortableCalculatePi = 3.14159264958921 took 00:00:09.6137173
BetterAbortableCalculatePi = 3.14159264958921 took
00:00:06.3826212
OptimisedAbortableCalculatePi = 3.14159265758921 took
00:00:03.6883268
As the figures show there is virtually no difference between the first and last run, but a considerable difference when cancellation is inserted into the core of the computation.
So to sum up whilst cancellation support is good the frequency you check for could have an impact on the overall performance of your algorithm. Cancellation is something we want to support but in general users probably don’t need it so we need to strike the right balance between throughput and responding to cancellation in an appropriate timeframe.
Just upload a new screencast covering how to marshal results from .NET 4 Tasks back on to the UI thread. One method is to continue to utilise the same API’s from previous versions of .NET thus utilising SynchronizationContext.Post, the Task based API offers an alternative and in some cases more elegant solution using the ContinueWith method.
Wenlong Dong has just posted about changes to the WCF thottling defaults in WCF 4.0. The new throttle defaults are going to be based on the number of processors/cores in the machine – this means the more powerful the machine the higher the throttle will be - which is a good thing. The throttle that always hit people first were either session, if they had a session as a result of contract/binding settings or, no session, concurrent calls. Now the changes (100 * processor count for session and 16 * processor count for calls) will mean that either one would bite first.
As Wenlong says, the original values were always too low for enterprise applications. What they did do, however, is force people to address throttling if they were writing enterprise apps. And Wenlong is right that that sometimes meant people putting the throttles up to int.MaxValue which is really the same as no throttle at all. But although, in general, I think the change is the right move (it mostly works out of the box), it will lead to people facing performance problems with absolutely no idea why they might be taking place.
What I mean by this is problems caused by the current throttles are really easy to spot “as soon as I put more than 10 calls though it breaks”. You can google that and find the problem and the solution. The new values make it hugely non-obvious why an application suddenly has problems with more than 400 clients (NetTcpBinding on machine with 4 cores for example). Good time to be a consultant in the UK and Europe I guess ;-)
Had a brief rest from patterns and parallel stuff to have a quick play with Silverlight 3. I mainly wanted to see the out of browser aspect, as I think the idea of being able to build RIA that also run on the desktop is very compelling….
So what to build, I really like the iPhone weather app so I thought I’d have a go at reproducing it in Silverlight, below is a screen shot showing it running out of the browser.
I’m using isolated storage to store the list of weather centre’s of interest, a more typical line of business app would store app config on the web server/cloud and potentially locally to support true client roaming, but I’ll leave that for another day.
One thing to note is that the method for enabling Out Of Browser mode for you application is now different from pre-release versions of Silverlight 3, so there are many old blog posts that are unfortunately wrong now. The good news is now it is trivial, view the project properties, and under the Silverlight tab there is an option to enable the app to support out of browser. This then creates the OutOfBrowserSettings.xml file.
You can download the source via here or to just see the app in action click here. I’ll let you decide if its as cool as the iPhone….
I’ve written many blog articles in the past that show that the performance of a piece of parallel code can vary dramatically based on the number of available cores. With that it mind, its obviously desirable even when given a machine with 8 cores that you test your code against a machine that could have substantially less. You can resort to task manager and set Process Affinity and reduce the number of cores available for the process, but this is tedious. There is a .NET API that allows access to controlling which cores to make available for a process. The API requires the use of a bitmask to identity which cores to use, that's a bit ( no pun intended) overkill for what I'm trying to do, so I created a facade that allows me to simply say use N cores.
public static class Cores
{
public static int Max
{
get
{
return Environment.ProcessorCount;
}
}
public static int CoresInUse
{
get
{
IntPtr cores =
Process.
GetCurrentProcess()
.ProcessorAffinity;
int nCores = 0;
while( cores != IntPtr.Zero )
{
if ( ((int)cores & 1) == 1 )
{
nCores++;
}
cores = (IntPtr)((int)cores >> 1);
}
return nCores;
}
set
{
if ((value < 1) || (value > Environment.ProcessorCount))
{
throw new ArgumentException("Illegal number of cores");
}
int cores = 1;
for (int nShift = 0; nShift < value-1; nShift++)
{
cores = 1 | (cores << 1);
}
Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)cores;
}
}
}
The following code prints out the number of active cores and then reduces the number of cores to 4
Console.WriteLine("Using {0} out of {1}" , Cores.CoresInUse , Cores.Max);
Cores.CoresInUse = 4;
Console.WriteLine("Using {0} out of {1}", Cores.CoresInUse, Cores.Max);
It has been one of the bug bears for me as I have given talks on the Azure platform that I have not been able to answer any question that involved commercial details with anything other than “we’ll have to see the prices when they announce them. Finally, today, the team have announced the pricing model and availability
Had loads of fun as normal teaching Guerilla .NET with Rich and Marcus , All the demos from class here
One of the frustrations with the current WCF tooling is that, although I can generate the client proxy code from a WSDL document I cannot generate the server side skeleton that matches the WSDL. In situations where two parties agree a contract based on WSDL this makes implementing the service side error prone. Back in the ASMX days WSDL.EXE had a /s switch that would create the service side skeleton, but this feature was not carried through into SVCUTIL.EXE.
Fortunately the WSCF (Web Service Contract First) guys have finally released a beta of a WCF compatible version of their tool that allows you to build up a model of the service and then generate the client and/or service
Here’s Santosh’s announcement
In my last post I linked to the screencast I made on processing large messages in WCF using buffering. I also said that I would be putting up another one on streaming messages shortly. That second screencast has now gone live on the Rock Solid Knowledge website. In part 2 of the large message handling screencast I talk about enabling streaming, designing contracts for streaming and how this affects the way the receiver has to process the data. You can find the new screencast here
http://rocksolidknowledge.com/ScreenCasts.mvc
Just released a screen cast demoing Parallel.For and Parallel.ForEach where we are not demoing the virtues of Parallel Sleep….
Click here to see this and many other Rock Solid Knowledge Screen casts
Just added a screen cast on how to create short and long running tasks in .NET 4. You can get to all the Rock Solid Knowledge screen casts via www.rocksolidknowledge.com/screencasts
I’ve just uploaded a new screencast on to Rock Solid Knowledge. This one walks though configuring WCF to be able to pass large messages between client and service. Its the of two parts, this one talks about the default mode WCF uses for transferring data – buffering. I’ll be doing another one soon that looks at WCF in streaming mode.
You can find the screencast here
Just to say that we will be delivering talks at Software Architect 2009, here is a full list of our sessions.
Been playing around with the new version of Pfx for .NET. I must say Ive been very impressed with the improvements since the last CTP for .NET 3.5. So here goes a series of blogs and screen casts on some on various bits of Pfx for .NET 4 BETA 1.
The one thing that really shouts is that the original Pfx types are no longer something for just fine grained parallelism its is a unification of the various threading API’s. Unifying Api’s is something not new to the .NET framework its been happening since 1.1. As developers its great that whilst the framework is evolving a constant effort is being made to refactor and simplify previous complexity.
So previously If I wanted to create a short running piece of background work I would favour the thread pool, if I was to write a long running piece of background activity I would have to create my own custom thread. Creating a short running thread using the thread pool meant either QueueUserWorkItem or Delegate.BeginInvoke, and a long running via new Thread(), and calling Start.
Now for either types of situation you simply create a new Task using the new Task type, either via the Task Factory ( not a real GOF Factory, but don’t get me started on that ), or via new Task()
Task bgTask = Task.Factory.StartNew( MyShortRunningTask);
For a long running task we use the same API but this time giving it a hint that this is a long running task and shouldn’t therefore use a thread pool thread, but create a new thread outside the thread pool
Task bgTask = Task.Factory.StartNew( MyLongRunningTask, TaskCreationOptions.LongRunning);
So too very similar calls but leaving it up to the framework to decide how best to schedule the work.
Just noticed that I can drag source windows outside the IDE in VS2010, this is something Ive wanted for ages…Now I can really use multiple monitors
I’ve written many articles on my blog about how Im sick of trade show demos of Pfx ( Parallel framework extensions ). You know the ones using simple Parallel.For with Thread.Sleep or Thread.SpinWait as the piece of work. These examples scale wonderfully but the moment people take those simple examples and apply them to their own for loops terrible performance often results. Thankfully the Pfx team have written a blog article offering some suggestions about what to do when the piece of work inside the for loop is too small. ( Blog article ). Interesting this is the first time I’ve seen them utilise the number of processors in the machine to determine the number of tasks, something I’ve advocated many times in the past for tasks of equal cost.
I am one of the moderators of the MSDN WCF Forum. One of the main areas of questions on the forum is duplex messaging – particularly using the WSDualHttpBinding. So instead of typing long messages repeating the same thing in answer to these questions I’ve decided to write this blog post to give a bit of background about duplex messaging and then discuss the options for bindings and common problems people have.
There are many ways that messages can be exchanged between two parties in a service based system: the client can send messages to the server and never get any back; the client can send a message and wait for a response; the client and service can send eachother messages without any pre-defined pattern; the client can send the service a message but not wait synchronously for a response and then then service can send a message back asynchronously; and there are many others. However, the first three of these are supported natively in WCF and are known as One-way, request/response and duplex.
So Duplex messaging is where, unsolicited, the client and service can send eachother messages. Most commonly this is characterized by the service sending the client “events” or notifications or progress of “interesting things”.
To send messages to eachother the client and service must have an idea of what operations are available and what messages are sent and received during the communication. In WCF this idea is modelled by the contract. Now normally a contract just determines what functionality is available at the service. However, now the service is going to be sending messages to the client that the client isn’t specifically waiting for so it needs an idea of what messages the client can deal with. So we need a contract that models both directions of the conversation.
A bi-directional contract is modelled using two interfaces bound together with a ServiceContract – like this:
[ServiceContract(CallbackContract=typeof(IPizzaProgress))]
interface IOrderPizza
{
[OperationContract]
void PlaceOrder(string PizzaType);
}
interface IPizzaProgress
{
[OperationContract]
void TimeRemaining(int minutes);
[OperationContract]
void PizzaReady();
}
The import bit here is the CallbackContract that establishes the relationship between the service’s and client’s contracts.
The service is implemented normally apart from two issues: firstly it needs to access the callback contract to be able to send messages back to the client; secondly the communication infrastructure (modelled by the binding) needs to be able to cope with duplex messaging. Firstly lets look at accessing the callback contract:
class PingService
: IOrderPizza
{
IPizzaProgress callback;
public void PlaceOrder(string PizzaType)
{
callback = OperationContext.Current.GetCallbackChannel();
Action preparePizza = PreparePizza;
preparePizza.BeginInvoke(ar => preparePizza.EndInvoke(ar), null);
}
void PreparePizza()
{
for (int i = 10 - 1; i >= 0; i--)
{
callback.TimeRemaining(i);
Thread.Sleep(1000);
}
callback.PizzaReady();
}
}
The critical line here is calling GetCallbackContract on the OperationContext. This gives the service access to a proxy to call back to the client.
Now the service also needs to use a contract that is compatible with duplex messaging. WSHttpBinding is the default for the built in WCF projects but it does not support duplex messaging. People generally then move to the WSDualHttpBinding which is similar to the WSHttpBinding but does support duplex. I will go into more depth about bindings for duplex shortly but for now lets stick to this for now - it will work in our test rig on a single machine without issue.
If the client is going to receive these messages it needs to provide an implementation of the callback contract. It can gets its definition from either a shared contract assembly or from metadata. If using metadata the callback contract will be named the same as the service’s contract but with the work Callback appended. It will also need to supply this implementation to the WCF infrastructure and it does this by wrapping an instance in an InstanceContext object and passing it to the proxy constructor. So here is the client:
class Program
{
static void Main(string[] args)
{
InstanceContext ctx = new InstanceContext(new Callback());
OrderPizzaClient proxy = new OrderPizzaClient(ctx);
proxy.PlaceOrder("Pepperoni");
Console.WriteLine("press
enter to exit");
Console.ReadLine();
}
}
class Callback
: IOrderPizzaCallback
{
public void TimeRemaining(int minutes)
{
Console.WriteLine("{0}
seconds remaining", minutes);
}
public void PizzaReady()
{
Console.WriteLine("Pizza
is ready");
}
}
Running the service and the client will have this working quite happily – so it would seem that duplex messaging and WCF works very well … so why on earth do people keep asking questions about it on the WCF forums?
Ahh well you probably did the thing that is obvious but almost always a bad idea. You went and chose WSDualHttpBinding as your duplex binding. To understand why this is a bad idea we need to dig a little deeper into how the WSDualHttpBinding works. HTTP is a unidirectional protocol: the client makes a request and the server sends a response. There is no way for a server to initiate an exchange with the client. So how on earth is duplex messaging going to work because it requires exactly this facility? Well the “Dual” in the name is significant, the WSDualHttpBinding actually consists of two connections: one outbound from client to server and one inbound from server to client – this second connection may already be ringing alarm bells with you. The are a two big problems with inbound connections to a client: firewalls very often block inbound connections to clients; the client may not be reachable from the server, it may be using NAT translation behind a router and so cannot be contacted without port forwarding being set up on the router. Both of these issues are showstoppers in real network topologies. You can take some small steps to help – you can specify what port the client should listen on for example by using the clientBaseAddress property of the WSDualHttpBinding. This means the network admin will only have to punch one hole in their firewall (but lets face it, network admins don’t allow any holes to be punched in the firewall).
So if you really shouldn’t use WSDualHttpBinding for duplex, what should you use instead? Well NetTcpBinding supports duplex out of the box and the nice thing about this is that the outbound connection that it establishes can also be used be used for inbound traffic – suddenly we don;t have the inbound connection firewall/NAT issues. “But hold on, isn’t NetTcpBinding for intranet? I’ve read books that tell me that in their ‘which binding should I use?’ flowcharts!” Well it turns out those flowcharts are talking rubbish – NetTcpBinding works very happily over the internet, its just not interoperable by design. “Aha! but I need interop so WSDualHttpBinding is for me!” Well unfortunately not, NetTcpBinding is non-interoperable by design, WSDualHttpBinding is non-interoperable despite its design. From the name it would suggest interoperability but Arun Gupta from Sun wrote this excellent post describing why it wasn’t.
So now seeing that we really are not talking about interop anyway, NetTcpBinding is far more useful than WSDualHttpBinding. Its not bullet proof, if the firewall only allows outbound port 80 but also allows inbound port 80, then WSDualHttpBinding would work where NetTcpBinding wouldn’t – but in this situation we’re really talking server to server and so I’d argue its probably better to roll your own bidirectional communication with two standard HTTP based connections.
The final option you have for duplex communication is to add a piece of infrastructure into the mix. The .NET Services Service Bus (part of the Azure platform) allows two parties to exchange messages both making outbound connections – potentially even using HTTP port 80. The two outbound connections rendezvous in the Service Bus which mediates their message exchanges. If the receiver has had to use outbound port 80 then it polls to receive message bound for it.
Irrespective if which of the standard bindings you are using, duplex assumes a constant relationship between proxy and service. In WCF this idea is modelled by the concept of session. All duplex bindings require session. A while back I wrote in some detail about sessions. You will have to either put up with increasing the session throttle (see the linked article for details) or roll your own custom binding that can do duplex without session – you can find an example of this here.
This is because your client is probably a Rich Client GUI based application (Windows Forms or WPF). To understand why this is a problem we need to step back briefly and look at UI clients, threading and WCF threading. UI applications have a rule: you must only update the UI from the thread that created those UI components. In general a GUI application has one UI thread so anything that changes the UI needs to be done from that thread. .NET 2.0 introduced a new construct to simplify the process of a background thread updating the UI: SynchronizationContext. The idea is that a UI framework creates an implementation of a SynchronizationContext derived class that handles the mechanics of marshalling a call on to the UI thread. An instance of this implementation is then made available on the UI and accessible via the SynchronizationContext.Current.
WCF adds more complexity into the mix by enforcing a rule that says “unless you tell me otherwise I will only allow one thread at a time into an object that I control”. You see this with singleton services that will only allow one call at a time by default. The same is also true of the callback implementation object – so WCF will only allow one active thread in the client at a time. So while WCF is performing an outbound call it will not allow an inbound call into the object. This causes the initial problem with the deadlock that the service’s callback cannot be dispatched while the client’s outbound call is in progress. To solve this we use the “unless you tell me otherwise” part of the above rule. You do this by annotating the callback implementation class with a [CallbackBehavior] attribute like this:
[CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]
class Callback
: IOrderPizzaCallback
{
public void TimeRemaining(int minutes)
{
Console.WriteLine("{0}
seconds remaining", minutes);
}
public void PizzaReady()
{
Console.WriteLine("Pizza
is ready");
}
}
But now there is another problem: by default WCF will attempt to dispatch using an available SynchronizationContext. The problem with this callback is the UI thread is already blocked in an outbound call. SO for the call to dispatch we need to tell WCF not to use the SynchronizationContext – again using the CallbackBehavior attribute:
[CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant, UseSynchronizationContext=false)]
class Callback
: IOrderPizzaCallback
{
...
}
Now the issue is of course that the call is going to be processed on a non UI thread so you would have to manually marshal any UI interaction using the SynchronizationContext.Post method.
Duplex messaging can be a useful message exchange pattern but in WCF there can be some unexpected issues. Hopefully this blog post clarifies those issues and demonstrates workarounds for them.