To assess how efficient your communication is, review the following questions:

Do you use chatty interfaces?
Do you make remote calls?
How do you exchange data with a remote server?
Do you have secure communication requirements?
Do you use message queues?
Do you make long-running calls?
Could you use application domains instead of processes?

Do You Use Chatty Interfaces?

Chatty interfaces require multiple round trips to perform a single operation. They result in increased processing overhead, additional authentication and authorization, increased serialization overhead, and increased network latency. The exact cost depends on the type of boundary that the call crosses and the amount and type of data passed on the call.

To help reduce the chattiness of your interfaces, wrap chatty components with an object that implements a chunky interface. It is the wrapper that coordinates the business objects. This encapsulates all the complexity of the business logic layer and exposes a set of aggregated methods that helps reduce round trips. Apply this approach to COM interop in addition to remote method calls.

Do You Make Remote Calls?

Making multiple remote calls incurs network utilization as well as increased processing overhead. Consider the following guidelines to help reduce round trips:

For ASP.NET applications, use client-side validation to reduce round trips to the server. For security reasons, also use server-side validation.

Implement client-side caching to reduce round trips. Because the client is caching data, the server needs to consider implementing data validation before initiating a transaction with the client. The server can then validate whether the client is working with a stale version of the data, which would be unsuitable for this type of transaction.

Batch your work to reduce round trips. When you batch your work, you may have to deal with partial success or partial failure. If you do not design for this, you may have a batch that is too big, which can result in deadlocks, or you may have an entire batch rejected because one of the parts is out of order.

How Do You Exchange Data with a Remote Server?

Sending data over the wire incurs serialization costs as well as network utilization. Inefficient serialization and sending more data than necessary are common causes of performance problems. Consider the following:

Do you use .NET remoting?

If you use .NET remoting, the BinaryFormatter reduces the size of data sent over the wire. The BinaryFormatter creates a binary format that is smaller in comparison to the SOAP format created by the SoapFormatter.

Use the [NonSerialized] attribute to mark any private or public data member that you do not want to be serialized.

Do you use ADO.NET DataSets?

If you serialize DataSets or other ADO.NET objects, carefully evaluate whether you really need to send them across the network. Be aware that they are serialized as XML even if you use the BinaryFormatter.

Consider the following design options if you need to pass ADO.NET objects over the wire in performance-critical applications:

Consider implementing custom serialization so that you can serialize the ADO.NET objects by using a binary format. This is particularly important when performance is critical and the size of the objects passed is large.

Consider using the DataSetSurrogate class for the binary serialization of DataSets.

Do you use Web services?

Web Services uses the XmlSerializer to serialize data. XML is transmitted as plain text, which is larger than a binary representation. Carefully evaluate the parameters and payload size for your Web service parameters. Make sure the average size of the request and response payload, multiplied by the expected number of concurrent users, is well within your network bandwidth limitations.

Make sure you mark any public member that does not need to be serialized with the [XmlIgnore] attribute. There are other design considerations that help you to reduce the size of data transmitted over the wire:

Prefer the data-centric, message-style design for your Web services. With this approach, the message acts as a data contract between the Web service and its clients. The message contains all of the information required to complete a logical operation.

Use the document/literal encoding format for your Web services because the payload size is significantly reduced in comparison to the document/encoded or RPC/encoded formats.

If you need to pass binary attachments, consider using Base64 encoding or, if you use Web Services Enhancements (WSE) at the client and server, consider using Direct Internet Message Encapsulation (DIME). The client can also have an implementation other than WSE that supports DIME format. For more information, see "Using Web Services Enhancements to Send SOAP Messages with Attachments" on MSDN at http://msdn.microsoft.com/library/en-us/dnwse/html/wsedime.asp.

For more information about Web services, see Chapter 10, "Improving Web Services Performance."

Do You Have Secure Communication Requirements?

If it is important to ensure the confidentiality and integrity of your data, you need to use encryption and keyed hashing techniques; they both have an inevitable impact on performance. However, you can minimize the performance overhead by using the correct algorithms and key sizes. Consider the following:

Do you use the right encryption algorithm and key size?

Depending on how sensitive the data is and how much security you need, you can use techniques ranging from simple encoding solutions to strong encryption. If you use encryption, where possible (when both parties are known in advance), use symmetric encryption instead of asymmetric encryption. Asymmetric encryption provides improved security but has a greater negative impact on performance. A common approach is to use asymmetric only to exchange a secret key and then to use symmetric encryption.

Do You Use Message Queues?

Using message queues allows you to queue work for a component without blocking for results. Message queues are particularly useful to decouple the front- and back-end components in a system and to improve system reliability. When processing is complete, the server can post results back to a client-side message queue, where each message can be identified and reconciled with a unique message ID. If necessary, you can use a dedicated background process on the client to process message responses.

To use a component-based programming model with message queuing, consider using Enterprise Services Queued Components.

Do You Make Long-Running Calls?

A long-running call can be any type of work that takes a long time to complete. Long is a relative term. Usually, long-running calls result from calling Web services, a remote database server, or a remote component. For a server application, long-running calls may end up blocking the worker, I/O threads, or both, depending on the implementation logic.

The following designs help you avoid the impact of blocking with long-running calls:

Use message queues. If the client requires a success indicator or results from the server process later on, use a client-side queue.

If the client does not need any data from the server, consider the [OneWay] attribute. With this "fire and forget" model, the client issues the call and then continues without waiting for results.

If a client makes a long-running call and cannot proceed without the results, consider asynchronous invocation. For server applications, asynchronous invocation allows the worker thread that invokes the call to continue and perform additional processing before retrieving the results. In most of the scenarios, if the results are not available at this point, the worker thread blocks until the results are returned.

Could You Use Application Domains Instead of Processes?

Cross-application domain communication is considerably faster than interprocess communication (IPC). Some scenarios where multiple application domains would be appropriate include the following:

Your application spawns a copy of itself often.

Your application spends a lot of time in IPC with local programs that work exclusively with your application.

Your application opens and closes other programs to perform work.

While cross-application domain communication is far faster than IPC, the cost of starting and closing an application domain can actually be more expensive. There are other limitations; for example, a fatal error in one application domain could potentially bring the entire process down and there could be resource limitation when all application domains share the same limited virtual memory space of the process.