WCF Simplified Part 4: Comparing the Request/Reply and One-Way Patterns
May 25, 2010 6 Comments
Today we’ll look at the differences between a request/reply pattern and a one-way pattern, using the simple WCF service application and client console app that we built in the introductory post.
1. In the WCF service app, in file IService1.cs, add a new OperationContract called PostData,
[ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); // Note the void return value [OperationContract] void PostData(int value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); }
2. Now in the file Service1.cs, add the implementation code,
public void PostData(int value) { // Do something with 'value' – simulate a 10-sec long process Thread.Sleep(10000); // Then throw an exception throw new Exception("Something went very wrong in the service library!"); }
3. And in the Main method in Program.cs,
using (ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary1.Service1), new Uri("http://localhost:8000/HelloWCF"))) { // Set up a service endpoint [Contract, Binding, Address] host.AddServiceEndpoint(typeof(WcfServiceLibrary1.IService1), new BasicHttpBinding(), "HelloWCF"); // Enable metadata exchange ServiceMetadataBehavior smb = new ServiceMetadataBehavior() { HttpGetEnabled = true }; host.Description.Behaviors.Add(smb); // Enable exception details ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>(); sdb.IncludeExceptionDetailInFaults = true; host.Open(); Console.WriteLine("Ready..."); Console.ReadLine(); }
4. Now on the client app, delete and re-add (or update) the Service Reference to the WCF service host. Then change the code in Main to,
EndpointAddress epoint = new EndpointAddress("http://localhost:8000/HelloWCF/HelloWCF"); ServiceReference1.IService1 proxy = ChannelFactory<ServiceReference1.IService1>.CreateChannel(new BasicHttpBinding(), epoint); using (proxy as IDisposable) { // Call the WCF service using the proxy Console.WriteLine("Start:" + DateTime.Now.ToLongTimeString());
try { proxy.PostData(42); } catch (FaultException fex) { Console.WriteLine(fex.Message); }
Console.WriteLine("Done:" + DateTime.Now.ToLongTimeString()); } Console.ReadLine();
5. Now running the client app, you should see that the client blocks for 10sec and then shows the exception message,
This shows that in a request/reply pattern the client blocks till it gets the reply from the service, and also the client is able to process the FaultException. Now let’s see what happens in a one-way pattern, simply change the PostData OperationContract to add a IsOneWay attribute,
[ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); // Add the IsOneWay attribute [OperationContract(IsOneWay=true)] void PostData(int value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); }
Now when you run the client (remember to delete and add the Service Reference – update should work too), you’ll see,
The client didn’t block on the call and returned immediately. It was also unable to process the FaultException because there is no reply message in a one-way pattern. To see this, try the following implementation of PostData,
public void PostData(int value) { // Do something with 'value' – simulate a 10-sec long process //Thread.Sleep(10000); // Just throw an exception – a one-way implementation will not catch this throw new Exception("Something went very wrong in the service library!"); }
Pingback: WCF Simplified Series « I.Net
Hehe I’m literally the first reply to your awesome read!
WCF Simplified Part 4: Comparing the Request/Reply and One-Way Patterns ? I.Net adler@gigemail.net
Simple and Awesome. You are making my WCF concepts better.
Great…
Thanks.
Does it mean we can use the request/reply pattern as a fail-safe communication, much like the MSMQ?