Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different forms of the WCF service contract interface

Tags:

It appears I can freely switch between the following three different versions of the same WCF contract interface API, without breaking the clients:

[ServiceContract] interface IService {     // Either synchronous     // [OperationContract]     // int SomeMethod(int arg);      // Or TAP     [OperationContract]     Task<int> SomeMethodAsync(int arg);      // Or APM     // [OperationContract(AsyncPattern = true)]     // IAsyncResult BeginSomeMethod(int arg, AsyncCallback callback, object state);     // int EndSomeMethod(IAsyncResult ar); } 

The existing test client app keeps working without any recompiling or touching. If I do recompile the service and re-import its reference into the client app, the WSDL definition remains the same, 1:1.

My questions:

  • Is it a legit behavior I can rely on? Is it documented anywhere?

The idea is to convert a set of synchronous SomeMethod-style methods into TAP SomeMethodAsync-style methods, to use async/await in their implementation and thus improve the WCF service scalability, without breaking existing clients.

Also, there have been known woes with WCF service scaling under .NET 3.5 and .NET 4.0. They are documented in the MSKB article "WCF service may scale up slowly under load" and the CodeProject article "Tweaking WCF to build highly scalable async REST API". Basically, it wasn't enough to implement the service contract APIs as naturally asynchronous, the WCF runtime still was blocking the request thread.

  • Does anyone know if this problem has been fixed for .NET 4.5.x, out-of-the-box? Or the additional tweaks are still required?
like image 701
noseratio Avatar asked Mar 25 '14 01:03

noseratio


People also ask

What type of contract is applicable to interface in WCF?

There are the following two types. The Service Contract declares an interface in the WCF service for the client to get access to the interface. The Operation Contract declares a function inside the interface, the client will call this function.

What can be used to define a WCF service contract?

A service contract can be declared using the [ServiceContract] attribute. It allows defining an Operation Contract under it to expose the service outside the world. It maps the interface and methods of your service to a platform-independent description.

Which contract type is not supported by WCF?

The service contract is not supported in the wcf client.

What are the main components of WCF?

The WCF service main components for creating and consuming the service are Address, Binding, and Contracts. It is also called as endpoints.


1 Answers

WCF operations can be defined using either synchronous, EAP or (as of .NET 4.5) TAP. From MSDN:

Clients can offer the developer any programming model they choose, so long as the underlying message exchange pattern is observed. So, too, can services implement operations in any manner, so long as the specified message pattern is observed.

You can actually have all 3 patterns in a single contract interface, and they would all relate to the same message.

On the wire, there's no difference how you execute the operations. WSDL (which WCF builds from each endpoint's ABC - address, binding and contract) doesn't contain this information. It is generated from operation descriptions.

If you look at the OperationDescription class, which is used in a ContractDescription, you'll see each operation has these properties: SyncMethod, BeginMethod, EndMethod and TaskMethod. When creating a description, WCF will combine all the methods according to the operation's name into a single operation. If there's some mismatch between operations with the same name in different patterns (e.g. different parameters) WCF would throw an exception detailing exactly what's wrong. WCF automatically assumes (optional) "Async" suffix for Task-based methods, and Begin/End prefix for APM.

The client and server side are completely unrelated in this sense. The utility that generates proxy classes from WSDL (svcutil), can build proxies for any execution pattern. It doesn't even have to be a WCF service.

On the server side, if more than one pattern is implemented, WCF will use just one in the following order of precedence: Task, Sync and APM. This is documented somewhere in MSDN, I just can't find it right now. But you can look at the reference source here.

In conclusion, you can safely change your server implementation as long as you don't modify the message the operation represents.

Regarding the scaling (should be a different question IMO)

  • WCF's throttling default values have been updated in .NET 4.5 to much more reasonable values and are now processor-dependent (see here).
  • There's no change in regards to the thread-pool issue. The problem stems from the initial size of the completion port thread-pool, which is initially set to 4 times the amount of the logical processors. You can use ThreadPool.SetMinThreads to increase the amount by some factor (see this post). This setting could also be beneficial on the client side.

If you use async on the server side (when calling other services, database, etc.), the threading situation could improve dramatically because you won't be wasting thread-pool threads that are just waiting for IO to complete.

The best thing in these situations is to do a LOT of benchmarking.

like image 142
Eli Arbel Avatar answered Oct 27 '22 09:10

Eli Arbel