2010-02-01 2 views
1

Как я могу реализовать односторонние действия WCF?Как реализовать IsOneWay = true в WCF nettcpBinding

Я просто попытался использовать атрибут IsOneWay как:

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

Есть ли другие изменения мне нужно сделать или какие-либо конкретные изменения в app.config?

FYI, мой сервис WCF реализует netTcpBinding, хотя я думаю, что это не должно иметь никакого значения.

+0

Вы получаете ошибку? Если да, уточните свой вопрос. –

+0

У меня нет ошибок :-(Клиентское приложение все еще ждет завершения всего процесса. – iniki

+0

Что это за вызов?Попробуйте настроить тривиальное примерное приложение с односторонним компонентом WCF и посмотреть, можете ли вы заставить его работать. Посмотрите, помогает ли эта проблема. –

ответ

1

Как показано, ваш код выглядит нормально. Не должно быть никаких проблем с выполнением односторонних вызовов с помощью netTcpBinding.

Если вам интересно, глава 5 в обзоре Juval Lowy Programming WCF Services 2nd Edition содержит полезную информацию об услугах в одну сторону.

От того, что вы показали, пока я не вижу ничего плохого. Пожалуйста, дайте нам более подробную информацию.

+0

И ссылка на онлайн-версию Juval's по этому вопросу. http://msdn.microsoft.com/en-us/magazine/cc163537.aspx – kenny

+0

Это потрясающий Кенни! :) Эта статья относится к WCF 3.0. Мне интересно, есть ли какие-то различия в 3.5 ... –

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 и затем закройте метод на прокси-сервер не возвращает, пока вызов не будет фактически завершен или раз позвонить вне. Вы когда-нибудь задумывались, почему это происходит?

Причина: Когда вы указываете «Односторонний» на вашем интерфейсе, операция базового канала по-прежнему выполняется в двух направлениях, поскольку односторонний элемент привязки не находится в стеке каналов. Таким образом, операция закрытия блокируется до завершения односторонней операции.

Это по дизайну, и команда разработчиков работает над ее изменением в будущих версиях .Net framework.

...

Решение (работа вокруг):

слой по 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(); 

Client Код:

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

Вы не должны просто указывать ссылку на другой сайт в качестве ответа, так как сайт может устареть в будущем. Вместо этого нажмите ссылку «изменить» в этом ответе и включите в нее основные части решения с этой страницы. См.: Http://meta.stackexchange.com/q/8259 –

+0

Спасибо, я сделаю это. –

Смежные вопросы