.net - WCF异步回调

标签 .net wcf asynchronous callback

我已经在代码中成功实现了 WCF 回调模式,现在我想实现异步回调。这是我的界面代码:

[ServiceContract(Name = "IMessageCallback")]
public interface IMessageCallback
{
  [OperationContract(IsOneWay = true)]
  void OnMessageAdded(string message, DateTime timestamp);
}

[ServiceContract(Name="IMessageCallback")]
public interface IAsyncMessageCallback
{
  [OperationContract(AsyncPattern = true)]
  IAsyncResult BeginOnMessageAdded(string msg, DateTime timestamp, AsyncCallback callback, object asyncState);
  void EndOnMessageAdded(IAsyncResult result);
}

[ServiceContract(CallbackContract = typeof(IMessageCallback))]
public interface IMessage
{
  [OperationContract]
  void AddMessage(string message);
}

为了使用同步回调,我声明了我的 channel 和端点,如下所示:

DuplexChannelFactory<IMessage> dcf = new DuplexChannelFactory<IMessage>(new InstanceContext(this), "WSDualHttpBinding_IMessage");
<endpoint address="net.tcp://localhost:8731/Message/"
            binding="netTcpBinding"
            contract="WCFCallbacks.IMessage" name="WSDualHttpBinding_IMessage">

我无法获得端点和 channel 的正确组合来利用异步回调。有人能指出我正确的方向吗?

另外当执行下面这行代码时:

OperationContext.Current.GetCallbackChannel<IAsyncMessageCallback>();

我收到以下错误:

Unable to cast transparent proxy to type 'WCFCallbacks.IAsyncMessageCallback'

最佳答案

您需要将服务协定 IMessage 的 CallbackContract 属性更改为该类型 (IAsyncMessageCallback)。下面的示例使用异步回调运行。

    public class StackOverflow_5979252
{
    [ServiceContract(Name = "IMessageCallback")]
    public interface IAsyncMessageCallback
    {
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginOnMessageAdded(string msg, DateTime timestamp, AsyncCallback callback, object asyncState);
        void EndOnMessageAdded(IAsyncResult result);
    }
    [ServiceContract(CallbackContract = typeof(IAsyncMessageCallback))]
    public interface IMessage
    {
        [OperationContract]
        void AddMessage(string message);
    }
    [ServiceBehavior(IncludeExceptionDetailInFaults = true, ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class Service : IMessage
    {
        public void AddMessage(string message)
        {
            IAsyncMessageCallback callback = OperationContext.Current.GetCallbackChannel<IAsyncMessageCallback>();
            callback.BeginOnMessageAdded(message, DateTime.Now, delegate(IAsyncResult ar)
            {
                callback.EndOnMessageAdded(ar);
            }, null);
        }
    }
    class MyClientCallback : IAsyncMessageCallback
    {
        public IAsyncResult BeginOnMessageAdded(string msg, DateTime timestamp, AsyncCallback callback, object asyncState)
        {
            Action<string, DateTime> act = (txt, time) => { Console.WriteLine("[{0}] {1}", time, txt); };
            return act.BeginInvoke(msg, timestamp, callback, asyncState);
        }

        public void EndOnMessageAdded(IAsyncResult result)
        {
            Action<string,DateTime> act = (Action<string,DateTime>)((System.Runtime.Remoting.Messaging.AsyncResult)result).AsyncDelegate;
            act.EndInvoke(result);
        }
    }
    static Binding GetBinding()
    {
        return new NetTcpBinding(SecurityMode.None);
    }
    public static void Test()
    {
        string baseAddress = "net.tcp://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(IMessage), GetBinding(), "");
        host.Open();
        Console.WriteLine("Host opened");

        InstanceContext instanceContext = new InstanceContext(new MyClientCallback());
        DuplexChannelFactory<IMessage> factory = new DuplexChannelFactory<IMessage>(instanceContext, GetBinding(), new EndpointAddress(baseAddress));
        IMessage proxy = factory.CreateChannel();
        proxy.AddMessage("Hello world");

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        ((IClientChannel)proxy).Close();
        factory.Close();
        host.Close();
    }
}

关于.net - WCF异步回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5979252/

相关文章:

c# - 有没有办法在 C# 中捕获调试消息,然后将它们输出到单独的窗口?

c# - 刷新DataGridView?

c# - 命名空间 'Objects' 中不存在类型或命名空间名称 'System.Data'

wcf - 我对 WCF 与 Internet 上的 SSL 的传输级安全性感到非常困惑

c# - 从字典值中获取所有项目,这些值也是项目列表

c# - .NET Web DLL 是否有类似 Application.ProductVersion 之类的东西?

c# - WCF 服务引用使用 XmlSerializer 创建临时动态程序集

javascript - 异步等待和获取语法在 React 中不起作用

ios - 如果在 PushViewController 之后完成,后端完成处理程序会使应用程序崩溃

c# - 如何知道异步调用何时真正开始?