0

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

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

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

哪个是问题?

谢谢。戴姆洛克。

4

1 回答 1

2

实现回调接口的类也需要实现异步方法(因为它们是在接口中定义的),但是如果一个接口同时具有相同方法的同步和同步版本,则默认调用同步方法。在下面的代码中,回调类中的异步操作只是抛出,但代码工作得很好。

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();
    }
}
于 2012-04-28T15:03:05.490 回答