/// <summary> /// This dispatches messages synchronously in the client, as we want to ensure that each message is processed in order, and without collision. /// </summary> /// <param name="message"> </param> /// <returns> </returns> public bool DispatchSynchronous(UrlEncodedMessage message) { return(_methodTargets[message.Command].With(method => { try { method.MethodInfo.Invoke(_targetObject, method.Parameters.Keys.Select(each => message.GetValue(each, method.Parameters[each].Type)).ToArray()); } catch (TargetInvocationException exception) { if (exception.InnerException != null) { if (exception.InnerException is RestartingException) { Logger.Message("Client recieved restarting message"); return false; } throw exception.InnerException; } } catch (AggregateException exception) { var c = exception.Unwrap(); Logger.Error(c); throw c; } catch (Exception exception) { Logger.Error(exception); throw exception; } return !(message.Command.Equals("TaskComplete") || message.Command.Equals("OperationCanceled")); }, () => { throw new MissingMethodException("Method '{0}' does not exist in this interface", message.Command); })); }
/// <summary> /// On the server side, we process messages asynchronously, as we want to make them as parallel as possible. /// </summary> /// <param name="message"> </param> /// <returns> </returns> public Task Dispatch(UrlEncodedMessage message) { return(_methodTargets[message.Command].With(method => Task.Factory.StartNew(() => { try { method.MethodInfo.Invoke(_targetObject, method.Parameters.Keys.Select(each => message.GetValue(each, method.Parameters[each].Type)).ToArray()); } catch (Exception e) { Logger.Error(e); } }, TaskCreationOptions.AttachedToParent), () => { throw new MissingMethodException("Method '{0}' does not exist in this interface", message.Command); })); }