public async Task basicRequest(HttpRequestInfo info)
        {
            //Jump out for request cancel
            info.Token.ThrowIfCancellationRequested();
            //Monitor
            //Basic data
            WebPageModel          page     = info.Page;
            ResponseData <string> received = null;
            var  monitor = info.RequestMonitor;
            bool requestResend;
            int  wrongDataRetryTimes = WrongReceiveRetryTimes;
            int  webErrorRetryTimes  = WebErrorRetryTimes;

            do
            {
                //Init
                requestResend = false;
                //Requesting
                monitor.IsRequesting = true;
                try
                {
                    received = await info.RequestTask(info.HttpRequestConfig, page.Url, info.Passing.Data, info.Token);
                }
                catch (AggregateException e)
                {
                    throw e;
                }
                catch (WebException e)
                {
                    if (webErrorRetryTimes > 0)
                    {
                        if (e.Response == null)
                        {
                            throw;
                        }
                        HttpWebResponse response = null;
                        if ((response = (e.Response as HttpWebResponse)) != null)
                        {
                            switch (response.StatusCode)
                            {
                            case HttpStatusCode.NotFound:
                            case HttpStatusCode.InternalServerError:
                            case HttpStatusCode.Forbidden:
                                throw;

                            default: break;
                            }
                            response.Dispose();
                        }
                        --wrongRetryTimes;
                        requestResend = true;
                        if (monitor.OnRetryRequest(e.Message) == RequestReceipt.Cancel)
                        {
                            break;
                        }
                    }
                }
                finally
                {
                    monitor.IsRequesting = false;
                }

                //Jump out for request cancel
                info.Token.ThrowIfCancellationRequested();

                //Hand result
                if (!requestResend)
                {
                    if (string.IsNullOrEmpty(received.Data))
                    {
                        if (wrongDataRetryTimes > 0)
                        {
                            if (monitor.OnRetryRequest(received.ErrorMessage) == RequestReceipt.Cancel)
                            {
                                break;
                            }
                            --wrongDataRetryTimes;
                            requestResend = true;
                        }
                    }
                    else
                    {
                        HandResult handResult = await info.HandDataTask(page, info.Passing, received);

                        if (handResult == HandResult.RequestResend)
                        {
                            requestResend = true;
                        }
                    }
                }
            } while (requestResend);
        }