protected override void ProcessCompletedTask(AsyncDataSourcePageTaskHolder completedTask, int currentDelay, int pageIndex, AsyncVirtualDataSourceProviderTaskDataHolder taskDataHolder)
{
ODataVirtualDataSourceProviderTaskDataHolder h = (ODataVirtualDataSourceProviderTaskDataHolder)taskDataHolder;
IDataSourceSchema schema = null;
IEnumerable<IDictionary<string, object>> result = null;
int schemaFetchCount = -1;
try
{
if (pageIndex == SchemaRequestIndex)
{
Task<int> task = (Task<int>)completedTask.Task;
schemaFetchCount = task.Result;
}
else
{
Task<IEnumerable<IDictionary<string, object>>> task = (Task<IEnumerable<IDictionary<string, object>>>)completedTask.Task;
result = task.Result;
}
}
catch (AggregateException e)
{
bool allCancels = true;
foreach (var ex in e.Flatten().InnerExceptions)
{
if (!(ex is TaskCanceledException))
{
allCancels = false;
}
}
if (!allCancels)
{
RetryIndex(pageIndex, currentDelay);
return;
}
else
{
RetryIndex(pageIndex, currentDelay);
return;
}
}
catch (TaskCanceledException e)
{
RetryIndex(pageIndex, currentDelay);
//TODO: other exceptions? Is there a way to skip this state for canceled stuff?
return;
}
IDataSourceExecutionContext executionContext;
DataSourcePageLoadedCallback pageLoaded;
lock (SyncLock)
{
if (schemaFetchCount >= 0)
{
ActualCount = schemaFetchCount;
}
else
{
var completedAnnotation = h.CompletedAnnotation;
if (completedAnnotation.Count.HasValue)
{
ActualCount = (int)completedAnnotation.Count.Value;
}
}
schema = ActualSchema;
}
if (schema == null)
{
schema = ResolveSchema();
}
lock (SyncLock)
{
ActualSchema = schema;
executionContext = ExecutionContext;
pageLoaded = PageLoaded;
}
ODataDataSourcePage page = null;
if (result != null)
{
page = new ODataDataSourcePage(result, schema, pageIndex);
lock (SyncLock)
{
if (!IsLastPage(pageIndex) && page.Count() > 0 && !PopulatedActualPageSize)
{
PopulatedActualPageSize = true;
ActualPageSize = page.Count();
}
}
}
else
{
page = new ODataDataSourcePage(null, schema, pageIndex);
}
if (PageLoaded != null)
{
if (ExecutionContext != null)
{
if (executionContext == null || pageLoaded == null)
{
Shutdown();
return;
}
executionContext.Execute(() =>
{
pageLoaded(page, ActualCount, ActualPageSize);
});
}
else
{
if (pageLoaded == null)
{
Shutdown();
return;
}
pageLoaded(page, ActualCount, ActualPageSize);
}
}
}