Posts Tagged ‘Event-based asynchronous’
- In: .NET | C# | Technical | WCF
- Leave a Comment
As a series of article, this time, I am going to introduce you with Event-based asynchronous communication. I have used here same service operation of IAsyncResult asynchronous operation that I have mentioned earlier. Service implementation and hosting are also same with IAsyncResult asynchronous. So, in this case I will not go to explain service section again as well as will not go for in details all parts as i have discussed it clearly in other two posts. I would suggest you to have a look on the given links first.
To develop a client is just straight forward. Here I have shown you a console app as a client,
public class Program { static void Main(string[] args) { var proxy = new MessageServiceProxy("MessageServiceEndpoint"); proxy.GetMessageCompleted += GetMessageCompleted; proxy.GetMessageAsync("HI"); Console.WriteLine("waiting"); Console.ReadLine(); } static void GetMessageCompleted(object sender, GetMessageCompletedEventArgs e) { Console.WriteLine(e.Result.ToString(CultureInfo.InvariantCulture)); } }
And its corresponding configuration has been given below,
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings /> <client> <endpoint address="http://localhost/Rashim.Rnd.WCF.Asynchronous.Services/" binding="basicHttpBinding" contract="Rashim.Rnd.WCF.Asynchronous.Services.IMessageService" name="MessageServiceEndpoint"> <identity> <dns value="ServerCertificate" /> </identity> </endpoint> </client> </system.serviceModel> </configuration>
Now the important thing is how we develop our ServiceProxy which in our case is MessageServiceProxy .
public class MessageServiceProxy : ClientBase<IMessageService>, IMessageService { public event EventHandler<GetMessageCompletedEventArgs> GetMessageCompleted; private BeginOperationDelegate _onBeginGetMessage; private EndOperationDelegate _onEndGetMessage; private SendOrPostCallback _onGetMessageCompleted; public MessageServiceProxy() { } public MessageServiceProxy(string endpointConfigurationName) : base(endpointConfigurationName) { } public IAsyncResult BeginGetMessage(string message, AsyncCallback callback, object asyncState) { return Channel.BeginGetMessage(message, callback, asyncState); } public string EndGetMessage(IAsyncResult result) { return Channel.EndGetMessage(result); } private IAsyncResult OnBeginGetMessage(object[] inValues, AsyncCallback callback, object asyncState) { var message = ((string)(inValues[0])); return BeginGetMessage(message, callback, asyncState); } private object[] OnEndGetMessage(IAsyncResult result) { string retVal = Channel.EndGetMessage(result); return new object[] { retVal}; } private void OnGetMessageCompleted(object state) { if ((GetMessageCompleted != null)) { var e = ((InvokeAsyncCompletedEventArgs)(state)); GetMessageCompleted(this, new GetMessageCompletedEventArgs(e.Results, e.Error, e.Cancelled, e.UserState)); } } public void GetMessageAsync(string message) { GetMessageAsync(message, null); } private void GetMessageAsync(string message, object userState) { if ((_onBeginGetMessage == null)) { _onBeginGetMessage = OnBeginGetMessage; } if ((_onEndGetMessage == null)) { _onEndGetMessage = OnEndGetMessage; } if ((_onGetMessageCompleted == null)) { _onGetMessageCompleted = OnGetMessageCompleted; } InvokeAsync(_onBeginGetMessage, new object[] { message}, _onEndGetMessage, _onGetMessageCompleted, userState); } }
Here I have used three delegates namely onBeginGetMessage, onEndGetMessage and onGetMessageCompleted and these three delegates will register when we first call GetMessageAsync() method. onGetMessageCompleted is a SendOrPostCallback which represents a callback method that we want to execute when a message is to be dispatched to a synchronization context.
Finally the GetMessageCompletedEventArgs,
public class GetMessageCompletedEventArgs : AsyncCompletedEventArgs { private readonly object[] _results; public GetMessageCompletedEventArgs(object[] results, Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { _results = results; } public string Result { get { RaiseExceptionIfNecessary(); return ((string)(_results[0])); } } }