如何在WCF nettcpBinding中实现IsOneWay = true

时间:2010-02-01 14:30:08

标签: wcf

如何实现单向WCF操作?

我刚尝试将IsOneWay属性用作:

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

我是否需要进行其他更改或app.config中的任何特定更改?

仅供参考,我的WCF服务实现了netTcpBinding,但我认为这不应该有任何区别。

2 个答案:

答案 0 :(得分:1)

如图所示,您的代码看起来不错。使用netTcpBinding进行单向调用应该没有问题。

如果您有兴趣,Juval Lowy的第5章很棒Programming WCF Services 2nd Edition包含有关单向服务的大量信息。

从你所展示的到目前为止,虽然我没有看到任何错误。请给我们更多细节。

答案 1 :(得分:1)

我们遇到的问题是单向调用没有立即使用NetTcpBinding返回。此博客文章确定了问题并提供了解决方案。

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

来自文章:

  

问题:在WCF服务中调用单向方法然后在代理上关闭方法的客户端在调用实际完成或调用超时之前不会返回。有没有想过为什么会这样?

     

原因:当您在接口上指定“One-Way”时,由于单向绑定元素不在通道堆栈中,因此基础通道操作仍然是双向的。因此,关闭操作将被阻止,直到单向操作完成。

     

这是设计使然,开发团队正在努力在未来版本的.Net框架中对其进行更改。

     

...

     

解决方案(解决方法):

     

将OneWayBindingElement层叠在netTcpBinding之上,如下面的代码所示。这样,对代理的近距离呼叫将立即返回,最终单向呼叫将以火灾的方式返回并忘记时尚。

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

public class Service1 : IService1
{
    public void SetData(int value)
    {
         //Application specific 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();

客户代码:

 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());`