Evaluating .NET smart client communications technology

In this article, IDesign's Brian Noyes presents the different technologies available for communication in a Smart Client application and how to choose between the options based on your application's needs. He covers performance characteristics of each option as well as security constraints on the choices made.

Once you choose to develop a .NET application as a smart client application, you have a number of design decisions

that you need to tackle. You need to design the presentation layer application (the client) as well as a back-end server architecture. You need to think about security, how you will deploy the application and whether you will support disconnected operations. One of the most critical design decisions you will need to make early in architecting the application is to choose a communications technology to connect the smart client application with back-end services. Those back-end services may be a database, middle-tier components on an application server or a Web service that you or a third party provides.

There are a number of viable choices for communications in a .NET application, and there is no one-size-fits-all answer. There are a number of decision criteria that you should evaluate against your particular application requirements, operational environment and development team skill set to help you select the right approach. In this article, I will discuss what your primary choices are, and what the pros and cons of each technology are with respect to the key decision criteria.

The communications a la carte menu

In a .NET smart client application, you really have five main choices you should consider for connecting the client application to back end services today. These same choices can also be used if you need to support peer-to-peer communications, although the pros and cons of each choice become a little different in that scenario. The five approaches you should consider include:

  • Client-server database connections
  • .NET Remoting
  • Enterprise Services
  • Web Services
  • MSMQ

Client-server database connections only make sense for small applications where scalability is not a concern, so I won't be discussing that approach any further. If you do decide to use straight database connections from the client to the database, you should at least be designing the client side application as a layered architecture for maintainability reasons. Likewise, even though MSMQ is a very powerful technology, it should only be used for certain specialized situations because it requires a fairly low-level programming approach, and has different calling semantics due to its one-way, asynchronous nature. If you need to make queued calls, you should consider using Enterprise Services queued components capabilities. So the list of choices for your .NET smart client application really boils down to Web services, .NET Remoting or Enterprise Services.

In another couple years, the menu will be much shorter, because from a development perspective, you will almost always want to use Indigo, the code name for the next generation communications programming interface for Windows. This technology will soon have a more formal name announced by Microsoft, but you can bet that people will continue to call it Indigo for quite some time. Indigo provides a single communications application programming interface (API) that you will code against, regardless of what kind of underlying communications transport you want to use.

It's good to know that Indigo is out there, and have a general sense of what it will do for you, but you need to build and ship applications today. So that brings you back to the menu presented earlier for the technologies that you can employ to connect your smart clients currently. To evaluate which of those you should select, there are a number of criteria you should consider, including performance, security, coupling, and deployment (not necessarily in that order). But because Indigo is just around the corner, another important criteria is how easy it will be to migrate to Indigo if you code your application against one of these other technologies today. I'll discuss each one of these criteria in turn, and address how each of the technologies stacks up against those criteria. Then at the end of the article, I'll sum up and give you some generalized guidance on which technology to select for a couple of common types of applications.

.NET smart client application performance

Even though performance is what people focus on most, from the perspective of the overall performance of your .NET smart client application, it is usually one of the least important aspects for selecting which remote communications model to use. If you look at the raw performance of making a simple method call through web services vs. remoting or Enterprise Services, then you will likely be frightened into thinking you should never use web services if you can avoid it.

To call a remote method via web services, the parameters of the method call have to be serialized into an XML envelope and passed through an HTTP request. They have to be parsed on the server side back into a stack frame that can be executed against the code that is servicing the method call. Any return values then have to be serialized back into an XML envelope that goes into the HTTP response back to the client. Finally the client has to parse that response and return the results to the caller. A similar process happens for either remoting or Enterprise Services, but both are much lower level, closer to the wire, have the option of using a faster binary serialization process.

The question most people ask is this: how much faster are .NET Remoting or Enterprise Services? The real question they should be asking, though, is this: does this performance difference matter? My assertion is that if you design your application wisely, it should not in most cases. If you compare the raw time to call a simple calculator method to add two integers and return a result, then you may see results that indicate that web services are hundreds or even thousands of times slower, depending on your network topology. However, normally when a client application makes a remote call to back end services, that call does more significant work on the server side, and often returns significantly more data than a single integer.

To emphasize this point, I put together a sample application that you can download that contains a smart client architecture that uses Web services, .NET Remoting, and Enterprise Services to invoke several kinds of back end functionality to compare the relative performance of each. The application architecture of the sample code is shown in Figure 1.

Multi-Channel Smart Client Demo Application figure

Figure 1: Multi-Channel Smart Client Demo Application

The ServiceObject class in the business layer exposes the basic functionality that the client is designed to consume. That functionality is then exposed through Web services, .NET Remoting, and Enterprise Services through lightweight shim classes for each technology. The client application consumes the service through each of those communications channels using the same calling pattern so that the performance of each channel can be compared. Each of those shim classes implements the same service interface, as shown below:

 public interface IServiceObject { int Add(int a, int b, out long timeTicks); void ComputeDiscountedRedProductSales(out long timeTicks); EmployeeDataSet GetEmployees(out long timeTicks); SalesDataSet GetSalesData(out long timeTicks); SalesOrderDetail[] GetSalesDetailCollection(out long timeTicks); }

The out parameters are used to measure the processing time on the server side and return it to the client for comparison with the overall processing time to make the remote call. This allows you to compare the cost of the remote communications to the cost of the server processing.

The client implements six simple use cases through the interface above to provide points of comparison for the performance of each protocol:

  • Add two integers on the server and return the result.
  • Return a relatively small set of data as a DataSet (approximately 300 rows of Employee data from AdventureWorks2000).
  • Return the same small set of data, but also data bind it on the client side.
  • Return a relatively large set of data as a DataSet (approximately 20000 rows of sales data from AdventureWorks2000).
  • Retrieve the same large data set on the server side, perform some per-row computation on that data, but return nothing to the client.
  • Return the same large data collection, but as a custom object collection instead of a DataSet.

The sample .NET smart client application will allow you to evaluate the performance of these operations through each of the three channels. It also gives you a tidy little reference application for seeing how to hook up the client and the server through the three technologies. I did a number of runs of the sample application on a 2GHz Centrino TabletPC machine, running everything locally. If this were run over a remote link, the latency of the network could obviously change the results some, but should affect each of the protocols about the same, other than having more impact on web services because of a larger payload in the messages.

The results of these test runs confirm the assertion that the relative performance of each technology is comparable when you are dealing with use cases that perform any amount of significant work on the server. Table 1 shows the average results for each use case. The numbers are shown in the form of server side processing time / total processing time. The precision of the measurements are only around 10-20 milliseconds, and varied by up to 50 milliseconds for each channel from run to run. The processing time for the simple addition method was so fast that it was below the margin of measurement and showed up as zero in most runs, as shown below:

Use Case Web Services (ms) Remoting (ms) Enterprise Services (ms)
Add two integers 0/10 0/0 0/0
Return small DataSet 10/180 10/170 10/160
Return small DataSet and data bind 10/190 10/180 10/170
Return large DataSet 410/3900 320/3900 370/3500
Perform computation on large DataSet on the server 2500/2500 2400/2400 2200/2200
Return large custom object collection 100/640 90/480 90/450

Table 1: Communications Performance Comparison -- Local Machine

The specific numbers above are relatively unimportant, but what is important to notice and understand are the trends. Across the board, the total processing time for use cases that involve any significant server side work are comparable, with only slightly noticeable advantage to .NET Remoting and Enteprise Services. One of the tricks here is to realize that even when passed over a binary communications channel like remoting or Enterprise Services, a .NET DataSet will be serialized as XML. So that is part of the reason why you will not see a noticeable difference in performance when you are returning data as a DataSet remotely.

However, the last two use cases show that even where you are not returning a DataSet, the difference in performance between the technologies is relatively small. For the use case where I retrieve approximately 20,000 rows of data and iterate over them performing a computation on the server side, remoting and Enterprise Services have a slight advantage, but not enough of one to dictate that you should use one or the other for your design.

The last use case is the most interesting for a couple of reasons. One is to notice the difference in processing time compared to returning a DataSet. In this case, the amount of data returned is the same as for the large DataSet. But the computation time is about 1/10 the cost of returning a DataSet. This is because of the XML serialization that occurs with a DataSet. So if you are returning large data collections, the performance impact of returning data via a custom object collection is far more significant than which communications technology you choose. You should also know that this can be remedied in the .NET Framework 2.0 by setting the RemotingFormat property on a DataSet to Binary, allowing you to still use data sets without the remoting performance penalty.

But the last use case is also the only one where there is a noticable relative performance difference between Web services, .NET Remoting, and Enterprise Services. Web services will be slower by a noticeable percentage than remoting or Enterprise Services, but only if you are passing large amounts of data that can be passed in a binary form when using .NET Remoting or Enterprise Services.

The bottom line is that the relative performance of Web services, .NET Remoting, and Enterprise Services should not significantly influence which technology you choose. You should really be focusing on the other factors discussed in the rest of this article. To ensure you have acceptable performance, you should limit the frequency and number of remote calls you make, and be careful about how much data you return in what form to the client.

Securing your remote communications

Out of the box today, neither Web services nor .NET Remoting have any built-in way of securing the communications between the client and the remote service. However, using Web Services Enhancements (WSE), you can easily secure a .NET Web service. Additionally, you can use SSL to secure the communications between the client and server in a point-to-point manner. However, when you do so, you give up some interoperability and performance. If your smart client application will run within the enterprise where the web service is exposed, then you can use Windows integrated security, which has its own performance drawbacks and obviously limits the platforms to Windows systems within a LAN/WAN environment.

Likewise, security can be layered onto remoting. In the .NET Framework 1.1, there is a reference custom sink that can be plugged into the remoting pipeline that gives you integrated security between the client and the server. You can find a sample of using this sink on the downloads page of the IDesign site. In the .NET Framework 2.0, this capability is built-in to the framework. You could also write a custom sink to provide security if you wanted to use some custom protocol. There is no interoperability between .NET remoting and anything else, so you don't give up anything else there, but there are some minor performance impacts of adding security to remoting as well.

Enterprise Services uses DCOM under the covers for its remote communications, and DCOM has a very strong, reliable and high performance infrastructure for security. However, this has the same limitations as .NET Remoting from an interoperability and coupling perspective -- you can only connect COM+ clients to COM+ servers. But if you want the strongest and fastest solution possible, Enterprise Services should be one of the first considerations.

Architecture coupling and deployment

The factors that really drive the cost and viability of a given design in the long term are those that reduce the total cost of ownership. That means picking a solution that is easy to develop, maintain, evolve and that still meets the other functional and non-functional requirements (such as performance, scalability and security).

An important factor in reducing the cost of development and maintenance of a system is reducing the degree of coupling that exists within the architecture. The more loosely coupled the client application is from the back-end, the more flexibility you will have in developing and deploying that client application. It also opens the door for other clients that you did not develop to consume your services, which can boost the profitability of many systems.

Coupling and deployment go hand-in-hand in many ways. A loosely coupled system is usually easier to deploy, because there are fewer pieces that have to be put in place to get the client and the server talking to one another in different deployment scenarios. There are other forms of coupling that need to be considered though, including how tightly coupled the client is to the server from a technology perspective, and how tightly coupled the application code is to a given technology.

Web services provide the loosest coupling that you can achieve in a .NET smart client application from a deployment perspective. As long as you can make HTTP requests from the client to the back-end, you can establish communications. If you need to move the server to a different location, all you have to do is change the address used on the client to make the requests. In fact, the client doesn't even have to be one that you built, it could be a third-party application, or some other Web application or service. As a consequence of this loose coupling, web services work very well for smart client applications that are automatically deployed over the network using technologies such as no-touch deployment or ClickOnce.

However, depending on how you use Web services, you can actually end up with a high degree of coupling in the client and server applications to the web services technology. If you use WSE to provide security, start using caching and session capabilities in ASP.NET to manage state, or directly manipulate the XML that gets transmitted, you very quickly end up coupling your application to the fact that you are using web services to achieve remote communications. Often you tie yourself to particular flavor of web services through the version of WSE or the .NET Framework that you are using.

From a deployment perspective, .NET remoting can look like an attractive option because all you have to do is deploy your assemblies and some configuration settings in your application configuration files, and you are ready to go. However, there is tight coupling from a network topology perspective because you need to be able to open specific ports to binary communications. This is sure the raise the hairs on the necks of your IT department. You are also tightly coupled from a technology perspective, in that only .NET clients are going to be able to consume your service.

Depending on what features in .NET Remoting you choose to use, you also become coupled to the technology within your application code. If you start managing lease lifetimes, introduce custom sinks, or start relying on passing remote object references back and forth between the client and server, you will find it very difficult to move from remoting to some other remote communications technology.


Enterprise Services also looks a little unappealing from a coupling perspective. To deploy a client that uses Enterprise Services, you also have to deploy an application proxy generated by COM+ on the application server via an MSI file. That means you need to have admin privilege to deploy the client application, and to update anything in it that affects the communications with the middle tier.

You might also think you are tightly coupled at the technology level, but you don't end up as coupled as you might think. Even though at the protocol level, the client has to be talking via COM+ to the server, the code that you write in your client application is usually very decoupled from the technology. You typically just create instances of the server components and access them through an interface reference. The COM+ infrastructure worries about creating the instance remotely and exposing a proxy to your runtime code. You rarely have any Enterprise Services specific code in the client. On the server, you decorate your classes and methods with Enterprise Service attributes to invoke the services that you need. However, you rarely have any code in your method bodies that exposes anything about the fact that it will execute within a COM+ environment. As a result, your application code is fairly loosely coupled to Enterprise Services.

Migrating your application to Indigo

If you are building a .NET smart client application today that you expect to be in operations for more than a few years, you need to consider the possibility that you will want to migrate that application to Indigo once Indigo is released. At a minimum, you might want to integrate your existing application with new services or clients that are using Indigo. The programming model for Indigo will simplify your application, while also allowing it to invoke or expose more complex services. However, the Indigo programming model is different from all three of the primary choices today. Additionally, the integration of the current technologies with Indigo have different paths.

The migration story to Indigo is a hot topic these days, and you will hear conflicting guidance on what kind of application will be easiest to migrate to Indigo. The ease of migration has a lot to do with the degree of coupling to the technology discussed in the previous section. If your application code is tightly coupled to web services, remoting, or Enterprise Services, you will have a harder time moving it forward to use Indigo instead. Depending on which technology you are using and how you are using it, you may or may not have an opportunity to integrate with an Indigo application.

I would argue that, in general, Enterprise Services applications give you the best opportunities for migration and integration. The programming style of Enterprise Services is that you derive your server components from the ServicedComponent base class and then you define interfaces to call those components. You add attributes at the class, interface, or method level to invoke the various services exposed through COM+. You rarely, if ever, write any code in your method bodies that have any Enterprise Service specifics in it.

The programming model of Indigo is very similar. You can define your service and data contracts through interfaces, which you decorate with attributes. You add additional services or behaviors through attributes. You configure the particular protocols and providers for those capabilities through application configuration files, allowing you to keep the communications protocol specifics out of your application code.

As a result, migrating an Enterprise Service application to Indigo will mostly be a matter of changing some attributes and namespaces. The amount of inline code that you have to modify should be minimal. Additionally, if you choose not to migrate, there will be a direct integration capability allowing you to consume or expose Indigo services from COM+ clients or services.

A similar argument could be made for Web services. Indigo can directly call web services, and can be consumed from Web service clients. In .NET, you create Web services by putting attributes on your classes and methods. However, to meet a lot of real-world requirements in a Web service application, you have to start introducing inline code that is coupled to the fact that you are doing web services. If you use WSE to provide security, you will have to upgrade to WSE 3.0 when it releases to be wire compatible with Indigo. You will have to regenerate proxies on the client because they are tightly coupled to the particular web service that they were generated against. If you are using any ASP.NET specific features, such as caching, session, or security, you will have to port that code to Indigo equivalents. So there are a number of ways that migrating an existing web service application will be more complicated than migrating an Enterprise Services application.

Remoting applications have some interesting arguments surrounding them as well. If you are using remoting in its simplest form, then it may be quite easy to migrate a remoting application to Indigo. However, if you are using custom leasing, sinks, or passing remote object references as method parameters, you will have a much more difficult time. These things do not exist in Indigo, and you will have to re-architect and re-implement all of these aspects to get your application to work in an Indigo world. Additionally, there will be no direct integration of remoting with Indigo, so migration is your only choice.


As I said at the beginning of the article, there is no one right answer for everyone for how to connect your smart client application to back-end services. You have to weigh the different benefits and drawbacks of each communications technology, and select the one who's pro's outweigh its cons. A couple of generalizations can be made though as a good starting point for most applications.

If you want the fastest, most secure, and most feature rich remote communications technology available for .NET smart client applications today, you should consider Enterprise Services. You will have to give up a little bit of deployment flexibility and will have to have an enterprise environment where the DCOM channels are allowed to communicate. Enterprise Services also have a steeper learning curve and a little more complexity in development because of the need to register components with COM+. But you will get a proven, rich, robust infrastructure for exposing and consuming services. This will also provide you with an easy migration and integration path to Indigo.

If you want the most loosely coupled and easy way to develop and maintain a solution, then Web services are probably your best choice. As I demonstrated in this article, the performance drawback of Web services is mostly insignificant for real business use cases, and there are ways to achieve suitable security. Migration and integration to Indigo will also be very feasible, although possibly with a little more effort than Enterprise Services.

Unless your application is small, short lived, and simple, I would stay away from .NET Remoting. Even though it appears simple and powerful on the surface, there are too many limitations for a large enterprise application for the long term.

Web services, remoting, and Enterprise Services all have their place for different kinds of applications, operating environments, and developer skill sets. Pick the one that makes the most sense for your application based on an educated and balanced considerations of their relative strengths and weaknesses.

Download demo for this article

About the author

Brian Noyes is a Microsoft Regional Director and MVP, and an international speaker, trainer, writer and consultant with IDesign Inc. He speaks at Microsoft TechEd US, Europe and Malaysia, Visual Studio Connections, SDC Netherlands, DevTeach Montreal, VSLive!, DevEssentials and other conferences, and is a top rated speaker on the INETA Speakers Bureau. He has published numerous articles on .NET development for The Server Side .NET, MSDN Magazine, MSDN Online, CoDe Magazine, Visual Studio Magazine, asp.netPRO, .NET Developer's Journal, and other publications. Brian's latest book, Data Binding with Windows Forms 2.0, part of the Addison-Wesley .NET Development Series, hit the shelves in January 2006, and will be followed this summer by Smart Client Deployment with ClickOnce.

This was first published in February 2008

Dig deeper on Smart client application development best practices



Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to: