/// <summary> /// Does the work of sending a call to the server, and waiting for the response. /// </summary> /// <param name="jsonRequest">The request to send</param> /// <returns>A Task result with the response</returns> private Task <TResponse> Send <TResponse>(IApiRequest jsonRequest, string channel, bool silentMode = false) where TResponse : IApiResponse, new() { TResponse output = default(TResponse); return(Task.Run(() => { ExceptionUtility.Try(() => { string jsonRequestString = JsonUtility.Serialize(jsonRequest); string jsonRequestStringForLogging = jsonRequestString.Replace(User.Current.Password, "********"); LogUtility.LogMessage(String.Format("{2}: Sending Request to {0}: {1}", this.Url, FormatJsonForLogging(jsonRequestStringForLogging), this._instanceId.ToString())); var waitHandle = new AutoResetEvent(false); bool gotResponse = false; Action <IApiResponse> receivedResponse = (r) => { gotResponse = true; if (r is Lib.Domain.Responses.ConnectionResponse && ((ConnectionResponse)r).IsSuccessful) { NotificationUtility.PostNotification(NotificationType.Reconnected); } if (r is Lib.Domain.Responses.ErrorResponse) { output = ResponseFactory.ParseResponse <TResponse>(r.RawResponse); } else { try { output = (TResponse)r; } catch (System.InvalidCastException ice) { LogUtility.LogException(ice, String.Format("The server returned a type of response that was not expected. The type of response expected was {0}", (typeof(TResponse)).Name), LogSeverity.Warn); output = default(TResponse); } } if (r.IsAuthFailure) { output = ResponseFactory.FabricateLoginFailureResponse <TResponse>(jsonRequest); } gotResponse = true; waitHandle.Set(); }; RegisterWaitingForResponse(channel, receivedResponse); if (_client != null) { _client.Send(new NSString(jsonRequestString)); waitHandle.WaitOne(DefaultSendTimeoutMs); UnregisterWaitingForResponse(channel); } //here we will fabricate an error response for case of timeout if (output == null && !gotResponse) { output = ResponseFactory.FabricateRequestTimeoutResponse <TResponse>(jsonRequest); this.FireRequestFailureEvent(jsonRequest, null, RequestFailureReason.Timeout, foregroundAction: (!silentMode)); } }); return output; })); }