protected void SelectAsync(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback)
        {
            if (!_owner.DataControl.Page.IsAsync)
            {
                throw new InvalidOperationException(Resources.ExtendedModelDataSourceView_MustBeAsyncPage);
            }

            _isAsyncSelect = true;

            DataSourceSelectResultProcessingOptions selectResultProcessingOptions = null;
            ModelDataSourceMethod modelMethod = EvaluateSelectMethodParameters(arguments, out selectResultProcessingOptions);
            ModelDataMethodResult result      = InvokeMethod(modelMethod);

            _owner.DataControl.Page.RegisterAsyncTask(new PageAsyncTask(async() =>
            {
                var selectResult = await(Task <SelectResult>) result.ReturnValue;
                if (arguments.RetrieveTotalRowCount)
                {
                    if (!selectResult.TotalRowCount.HasValue)
                    {
                        throw new InvalidOperationException(Resources.ExtendedModelDataSourceView_TotalRowCountNotSet);
                    }
                    arguments.TotalRowCount = selectResult.TotalRowCount.Value;
                }

                _isAsyncSelect = false;

                callback(CreateSelectResult(selectResult.Results));
            }));
        }
        protected override ModelDataSourceMethod EvaluateSelectMethodParameters(DataSourceSelectArguments arguments, out DataSourceSelectResultProcessingOptions selectResultProcessingOptions)
        {
            if (!_isAsyncSelect)
            {
                // Not doing async so just delegate to the base
                return(base.EvaluateSelectMethodParameters(arguments, out selectResultProcessingOptions));
            }

            IOrderedDictionary    controlValues         = MergeSelectParameters(arguments);
            ModelDataSourceMethod modelDataSourceMethod = FindMethod(this.SelectMethod);
            Type returnType = modelDataSourceMethod.MethodInfo.ReturnType;
            Type modelType  = ModelType;

            if (modelType == null)
            {
                foreach (var genericTypeArg in returnType.GetGenericArguments())
                {
                    if (typeof(IQueryable <>).MakeGenericType(genericTypeArg).IsAssignableFrom(returnType))
                    {
                        modelType = genericTypeArg;
                    }
                }
            }
            var queryableModelType   = (modelType != null) ? typeof(IQueryable <>).MakeGenericType(modelType) : null;
            var isReturningQueryable = (queryableModelType != null) && queryableModelType.IsAssignableFrom(returnType);
            var autoPage             = false;
            var autoSort             = false;

            if ((arguments.StartRowIndex >= 0) && (arguments.MaximumRows > 0))
            {
                autoPage = IsAutoPagingRequired(modelDataSourceMethod.MethodInfo, isReturningQueryable, _isAsyncSelect);
            }
            if (!String.IsNullOrEmpty(arguments.SortExpression))
            {
                autoSort = IsAutoSortingRequired(modelDataSourceMethod.MethodInfo, isReturningQueryable);
            }
            selectResultProcessingOptions = new DataSourceSelectResultProcessingOptions {
                ModelType = modelType, AutoPage = autoPage, AutoSort = autoSort
            };
            EvaluateMethodParameters(DataSourceOperation.Select, modelDataSourceMethod, controlValues);
            return(modelDataSourceMethod);
        }