【问题标题】:WCF: callback contract no async, error because no implement Begin/End methodsWCF:回调合约没有异步,错误,因为没有实现 Begin/End 方法
【发布时间】:2012-04-28 10:44:13
【问题描述】:

我有一个双工 WCF 服务。在服务合同中,我有 3 个异步方法和 1 个普通方法(关闭会话)。在 tha 回调合约中,我只有 1 个非异步的 void 方法。

当我使用 svcUtil 生成代理时,我使用 /a 参数,并获取 .cs。如果我打开这个文件,我可以看到为合约的 no async 方法生成了 Begin/end 方法,我不知道为什么,因为这个方法在合约中没有标记为异步。无论如何,这不是问题。

问题在于回调合约的方法。在我的客户端应用程序中,我实现了回调接口,但我实现了一个方法,一个同步方法,所以我没有 Begin/End 方法。但是,我无法编译,因为我有一个错误,即实现回调接口的类没有实现 Begin/end 方法。

问题出在哪里?

谢谢。 戴姆洛克。

【问题讨论】:

    标签: wcf asynchronous callback duplex


    【解决方案1】:

    实现回调接口的类也需要实现异步方法(因为它们是在接口中定义的),但如果一个接口同时具有同一方法的同步和同步版本,synchronous one is invoked by default。在下面的代码中,回调类中的异步操作只是抛出,但代码运行良好。

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

    【讨论】:

    • 你有什么理由通过线程ThreadPool.QueueUserWorkItem(delegate { callback.OnHello(text); });调用回调?你会这么好心地建议人们如何称呼异步BeginOnHelloEndOnHello 是否按命名约定调用?
    猜你喜欢
    • 2017-06-15
    • 1970-01-01
    • 2015-10-06
    • 2018-03-11
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多