Dot-Net
WCF 非同步回調
我已經在我的程式碼中成功實現了 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); }要使用同步回調,我聲明了我的通道和端點,如下所示:
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">我無法正確組合端點和通道來利用非同步回調。有人可以指出我正確的方向嗎?
此外,當執行以下程式碼行時:
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(); } }