1

How can I implement one way WCF operations?

I just tried using IsOneWay attribute as:

[OperationContract(IsOneWay=true)]
void MethodName(string param1, int param2)

Is there any other change I need to make or any specific change in app.config?

FYI, my WCF service implements netTcpBinding, though I think that shouldn't make any difference.

inutan
  • 10,558
  • 27
  • 84
  • 126
  • Are you getting an error? If so, please update your question. – Tad Donaghe Feb 01 '10 at 15:22
  • I am not getting any error :-( The client application still waiting for the whole process to finish. – inutan Feb 01 '10 at 15:44
  • What is this method calling? Try setting up a trivial sample app with a one-way WCF component and see if you can get that to work. Then see if that helps with this issue. – Tad Donaghe Feb 02 '10 at 19:43

2 Answers2

1

As shown, your code looks ok. There should be no problem with doing one-way calls with netTcpBinding.

If you're interested, chapter 5 in Juval Lowy's awesome Programming WCF Services 2nd Edition contains a good bit of information about one-way services.

From what you've shown, so far though I don't see anything wrong. Please give us some more details.

Tad Donaghe
  • 6,625
  • 1
  • 29
  • 64
  • And a link to an online version of Juval's on the subject. http://msdn.microsoft.com/en-us/magazine/cc163537.aspx – kenny Feb 01 '10 at 15:32
  • That's awesome kenny! :) That article refers to WCF 3.0. I'm wondering if there are any differences in 3.5... – Tad Donaghe Feb 01 '10 at 15:42
1

We had a problem with one-way calls not returning immediately using the NetTcpBinding. This blog post identifies the problem and provides a solution.

http://blogs.msdn.com/b/distributedservices/archive/2009/02/12/client-proxy-close-method-call-does-not-finish-immediately-in-one-way-wcf-calls.aspx

From the article:

Problem: Clients calling a one-way method in WCF Service and then close method on proxy does not return until the call is actually finished or call times out. Ever wonder why this happens?

Cause: When you specify “One-Way” on your interface, the underlying channel operation is still two-way since the one way binding element is not in the channel stack. Thus, the close operation gets blocked until the one way operation completes.

This is by design and the development team is working to change it in future versions of .Net framework.

...

Solution (Work around):

Layer the OneWayBindingElement on top of netTcpBinding as shown in the below code. This way, close call on proxy will return immediately and eventually the one-way call will return in fire and forget fashion.

[ServiceContract]
public interface IService1
{
    [OperationContract(IsOneWay = true)]
    void SetData(int value);
}

public class Service1 : IService1
{
    public void SetData(int value)
    {
         //Application specific code
    }
}

Service Host code:

        Form1ServiceHost = new ServiceHost(this, new Uri("net.tcp://localhost:8091/WindowsFormApp/Form1/"), new Uri("http://localhost:8090/WindowsFormApp/Form1/"));

        Binding binding = new NetTcpBinding();
        BindingElementCollection oldBindingElements = binding.CreateBindingElements();
        BindingElementCollection bindingElements = new BindingElementCollection();
        bindingElements.Add(new OneWayBindingElement());
        foreach (BindingElement bindingElement in oldBindingElements)
        {
            bindingElements.Add(bindingElement);
        }

        binding = new CustomBinding(bindingElements);

        Form1ServiceHost.AddServiceEndpoint("WCFServiceLibrary.IService1", binding, "");
        Form1ServiceHost.Open();

Client Code:

 Binding binding = new NetTcpBinding();
        BindingElementCollection oldBindingElements = binding.CreateBindingElements();
        BindingElementCollection bindingElements = new BindingElementCollection();
        bindingElements.Add(new OneWayBindingElement());
        foreach (BindingElement bindingElement in oldBindingElements)
        {
            bindingElements.Add(bindingElement);
        }

        binding = new CustomBinding(bindingElements);

        Service1Client client = new Service1Client(binding, new EndpointAddress("net.tcp://localhost:8091/WindowsFormApp/Form1/"));
        client.SetData(10);
        Console.WriteLine("set data");
        Console.WriteLine("Now closing the channel,Before close, current time is {0}", DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
        client.Close();
        Console.WriteLine("Now closing the channel,After close, current time is {0}", DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());`
Community
  • 1
  • 1
  • 1
    You shouldn't just give a link to another site as an answer, since the site may go out of date in the future. Instead, click the "edit" link on this answer and include the essential parts of the solution from that page here. See: http://meta.stackexchange.com/q/8259 – Peter O. Feb 12 '12 at 08:40