private void DoDispatch <T>( Dictionary <string, string> parametersDict, Action <VKBackendResult <T> > callback, Func <string, T> customDeserializationFunc = null) { parametersDict["v"] = VKSDK.API_VERSION; var accessToken = VKSDK.GetAccessToken(); if (accessToken != null) { parametersDict["access_token"] = accessToken.AccessToken; } var dispatchUri = string.Format(REQUEST_BASE_URI_FRM, _parameters.MethodName); VKHttpRequestHelper.DispatchHTTPRequest( dispatchUri, parametersDict, (httpResult) => { if (httpResult.IsSucceeded) { var backendResult = GetBackendResultFromString <T>(httpResult.Data, customDeserializationFunc); if (backendResult.ResultCode == VKResultCode.CaptchaRequired) { var captchaRequest = new VKCaptchaUserRequest { CaptchaSid = backendResult.Error.captcha_sid, Url = backendResult.Error.captcha_img }; VKSDK.InvokeCaptchaRequest(captchaRequest, (captchaResponse) => { if (!captchaResponse.IsCancelled) { var parametersWithCaptcha = new Dictionary <string, string>(parametersDict); parametersWithCaptcha["captcha_sid"] = captchaResponse.Request.CaptchaSid; parametersWithCaptcha["captcha_key"] = captchaResponse.EnteredString; DoDispatch(parametersWithCaptcha, callback, customDeserializationFunc); } else { InvokeSafely(() => callback(new VKBackendResult <T>() { ResultCode = VKResultCode.CaptchaControlCancelled })); } }); } else if (backendResult.ResultCode == VKResultCode.ValidationRequired) { var validationRequest = new VKValidationRequest { ValidationUri = backendResult.Error.redirect_uri }; VKSDK.InvokeValidationRequest(validationRequest, (vr) => { if (vr.IsSucceeded) { DoDispatch(parametersDict, callback, customDeserializationFunc); } else { InvokeSafely(() => callback(new VKBackendResult <T> { ResultCode = VKResultCode.ValidationCanceslledOrFailed })); } }); } else { InvokeSafely(() => callback(backendResult)); } } else { var backendResult = new VKBackendResult <T> { ResultCode = VKResultCode.CommunicationFailed }; InvokeSafely(() => callback(backendResult)); } }); }