WCF: договор за обратно извикване без асинхронен, грешка, защото не са внедрени методи за начало/край

Имам дуплексна WCF услуга. В договора за услуга имам 3 асинхронни метода и 1 нормален метод (затваряне на сесия). В договора за обратно извикване имам само 1 void метод, който не е асинхронен.

Когато генерирам проксито със svcUtil, използвам параметъра /a и получавам .cs. Ако отворя този файл, мога да видя, че се генерира методът Begin/end за метода без асинхронност на договора, не знам защо, защото този метод не е маркиран като асинхронен в договора. Както и да е, това не е проблемът.

Проблемът е в метода на договора за обратно извикване. В моето клиентско приложение прилагам интерфейса за обратно извикване, но внедрих един метод, метод за синхронизиране, така че нямам методите за начало/край. Въпреки това не мога да компилирам, защото имам грешка, че класът, който имплементира интерфейса за обратно извикване, не имплементира методите Begin/end.

Кой е проблемът?

Благодаря. Daimroc.


person Álvaro García    schedule 28.04.2012    source източник


Отговори (1)


Класът, който имплементира интерфейса за обратно извикване, трябва да имплементира и асинхронните методи (тъй като те са дефинирани в интерфейса), но ако интерфейсът има както синхронни, така и синхронни версии на същия метод, синхронният се извиква по подразбиране. В кода по-долу асинхронните операции в класа за обратно извикване просто хвърлят, но кодът работи добре.

public class StackOverflow_10362783
{
    [ServiceContract(CallbackContract = typeof(ICallback))]
    public interface ITest
    {
        [OperationContract]
        string Hello(string text);
    }
    [ServiceContract]
    public interface ICallback
    {
        [OperationContract(IsOneWay = true)]
        void OnHello(string text);

        [OperationContract(IsOneWay = true, AsyncPattern = true)]
        IAsyncResult BeginOnHello(string text, AsyncCallback callback, object state);
        void EndOnHello(IAsyncResult asyncResult);
    }
    public class Service : ITest
    {
        public string Hello(string text)
        {
            ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
            ThreadPool.QueueUserWorkItem(delegate
            {
                callback.OnHello(text);
            });

            return text;
        }
    }
    class MyCallback : ICallback
    {
        AutoResetEvent evt;
        public MyCallback(AutoResetEvent evt)
        {
            this.evt = evt;
        }

        public void OnHello(string text)
        {
            Console.WriteLine("[callback] OnHello({0})", text);
            evt.Set();
        }

        public IAsyncResult BeginOnHello(string text, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        public void EndOnHello(IAsyncResult asyncResult)
        {
            throw new NotImplementedException();
        }
    }
    public static void Test()
    {
        string baseAddress = "net.tcp://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(ITest), new NetTcpBinding(SecurityMode.None), "");
        host.Open();
        Console.WriteLine("Host opened");

        AutoResetEvent evt = new AutoResetEvent(false);
        MyCallback callback = new MyCallback(evt);
        DuplexChannelFactory<ITest> factory = new DuplexChannelFactory<ITest>(
            new InstanceContext(callback),
            new NetTcpBinding(SecurityMode.None),
            new EndpointAddress(baseAddress));
        ITest proxy = factory.CreateChannel();

        Console.WriteLine(proxy.Hello("foo bar"));
        evt.WaitOne();

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
person carlosfigueira    schedule 28.04.2012
comment
Има ли причина да извиквате обратното извикване чрез нишка ThreadPool.QueueUserWorkItem(delegate { callback.OnHello(text); });? Ще бъдете ли така любезен да посъветвате как да се извика като async BeginOnHello? Извиква ли се EndOnHello чрез конвенция за именуване? - person morleyc; 16.09.2015