Esempio n. 1
0
        void IDkmClrResultProvider.GetResult(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection <string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine <DkmEvaluationAsyncResult> completionRoutine)
        {
            if (formatSpecifiers == null)
            {
                formatSpecifiers = Formatter.NoFormatSpecifiers;
            }
            if (resultFullName != null)
            {
                ReadOnlyCollection <string> otherSpecifiers;
                resultFullName = FullNameProvider.GetClrExpressionAndFormatSpecifiers(inspectionContext, resultFullName, out otherSpecifiers);
                foreach (var formatSpecifier in otherSpecifiers)
                {
                    formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, formatSpecifier);
                }
            }
            var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationAsyncResult.CreateErrorResult(e)));

            wl.ContinueWith(
                () => GetRootResultAndContinue(
                    value,
                    wl,
                    declaredType,
                    declaredTypeInfo,
                    inspectionContext,
                    resultName,
                    resultFullName,
                    formatSpecifiers,
                    result => wl.ContinueWith(() => completionRoutine(new DkmEvaluationAsyncResult(result)))));
        }
Esempio n. 2
0
 void IDkmClrResultProvider.GetResult(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     if (formatSpecifiers == null)
     {
         formatSpecifiers = Formatter.NoFormatSpecifiers;
     }
     if (resultFullName != null)
     {
         ReadOnlyCollection<string> otherSpecifiers;
         resultFullName = FullNameProvider.GetClrExpressionAndFormatSpecifiers(inspectionContext, resultFullName, out otherSpecifiers);
         foreach (var formatSpecifier in otherSpecifiers)
         {
             formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, formatSpecifier);
         }
     }
     var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationAsyncResult.CreateErrorResult(e)));
     wl.ContinueWith(
         () => GetRootResultAndContinue(
             value,
             wl,
             declaredType,
             declaredTypeInfo,
             inspectionContext,
             resultName,
             resultFullName,
             formatSpecifiers,
             result => wl.ContinueWith(() => completionRoutine(new DkmEvaluationAsyncResult(result)))));
 }
Esempio n. 3
0
        void IDkmClrResultProvider.GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine <DkmGetChildrenAsyncResult> completionRoutine)
        {
            var dataItem = evaluationResult.GetDataItem <EvalResultDataItem>();

            if (dataItem == null)
            {
                // We don't know about this result.  Call next implementation
                evaluationResult.GetChildren(workList, initialRequestSize, inspectionContext, completionRoutine);
                return;
            }

            var expansion = dataItem.Expansion;

            if (expansion == null)
            {
                var enumContext = DkmEvaluationResultEnumContext.Create(0, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult));
                completionRoutine(new DkmGetChildrenAsyncResult(new DkmEvaluationResult[0], enumContext));
                return;
            }

            // Evaluate children with InspectionContext that is not the root.
            inspectionContext = inspectionContext.With(NotRoot);

            var rows = ArrayBuilder <EvalResult> .GetInstance();

            int index = 0;

            expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, 0, initialRequestSize, visitAll: true, index: ref index);
            var numRows = rows.Count;

            Debug.Assert(index >= numRows);
            Debug.Assert(initialRequestSize >= numRows);
            var initialChildren = new DkmEvaluationResult[numRows];
            CompletionRoutine <Exception> onException = e => completionRoutine(DkmGetChildrenAsyncResult.CreateErrorResult(e));
            var wl = new WorkList(workList, onException);

            wl.ContinueWith(() =>
                            GetEvaluationResultsAndContinue(evaluationResult, rows, initialChildren, 0, numRows, wl, inspectionContext,
                                                            () =>
                                                            wl.ContinueWith(
                                                                () =>
            {
                var enumContext = DkmEvaluationResultEnumContext.Create(index, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult));
                completionRoutine(new DkmGetChildrenAsyncResult(initialChildren, enumContext));
                rows.Free();
            }),
                                                            onException));
        }
Esempio n. 4
0
        private void GetItemsAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, int startIndex, int count, DkmInspectionContext inspectionContext, DkmCompletionRoutine <DkmEvaluationEnumAsyncResult> completionRoutine)
        {
            var expansion = dataItem.Expansion;
            var value     = dataItem.Value;
            var rows      = ArrayBuilder <EvalResultDataItem> .GetInstance();

            if (expansion != null)
            {
                int index = 0;
                expansion.GetRows(this, rows, inspectionContext, dataItem, value, startIndex, count, visitAll: false, index: ref index);
            }
            var numRows = rows.Count;

            Debug.Assert(count >= numRows);
            var results = new DkmEvaluationResult[numRows];
            var wl      = new WorkList(workList, e => completionRoutine(DkmEvaluationEnumAsyncResult.CreateErrorResult(e)));

            GetEvaluationResultsAndContinue(rows, results, 0, numRows, wl, inspectionContext, value.StackFrame,
                                            () => wl.ContinueWith(
                                                () =>
            {
                completionRoutine(new DkmEvaluationEnumAsyncResult(results));
                rows.Free();
            }));
            wl.Execute();
        }
Esempio n. 5
0
        private void GetChildrenAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, DkmStackWalkFrame stackFrame, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine <DkmGetChildrenAsyncResult> completionRoutine)
        {
            var expansion = dataItem.Expansion;
            var rows      = ArrayBuilder <EvalResultDataItem> .GetInstance();

            int index = 0;

            if (expansion != null)
            {
                expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, 0, initialRequestSize, visitAll: true, index: ref index);
            }
            var numRows = rows.Count;

            Debug.Assert(index >= numRows);
            Debug.Assert(initialRequestSize >= numRows);
            var initialChildren = new DkmEvaluationResult[numRows];
            var wl = new WorkList(workList, e => completionRoutine(DkmGetChildrenAsyncResult.CreateErrorResult(e)));

            GetEvaluationResultsAndContinue(rows, initialChildren, 0, numRows, wl, inspectionContext, stackFrame,
                                            () => wl.ContinueWith(
                                                () =>
            {
                var enumContext = DkmEvaluationResultEnumContext.Create(index, stackFrame, inspectionContext, new EnumContextDataItem(dataItem));
                completionRoutine(new DkmGetChildrenAsyncResult(initialChildren, enumContext));
                rows.Free();
            }));
            wl.Execute();
        }
Esempio n. 6
0
        private void GetChild(
            DkmEvaluationResult parent,
            WorkList workList,
            EvalResult row,
            DkmCompletionRoutine <DkmEvaluationAsyncResult> completionRoutine)
        {
            var inspectionContext = row.InspectionContext;

            if ((row.Kind != ExpansionKind.Default) || (row.Value == null))
            {
                CreateEvaluationResultAndContinue(
                    row,
                    workList,
                    row.InspectionContext,
                    parent.StackFrame,
                    child => completionRoutine(new DkmEvaluationAsyncResult(child)));
            }
            else
            {
                var typeDeclaringMember = row.TypeDeclaringMemberAndInfo;
                var name = (typeDeclaringMember.Type == null) ?
                           row.Name :
                           GetQualifiedMemberName(row.InspectionContext, typeDeclaringMember, row.Name, FullNameProvider);
                row.Value.GetResult(
                    workList.InnerWorkList,
                    row.DeclaredTypeAndInfo.ClrType,
                    row.DeclaredTypeAndInfo.Info,
                    row.InspectionContext,
                    Formatter.NoFormatSpecifiers,
                    name,
                    row.FullName,
                    result => workList.ContinueWith(() => completionRoutine(result)));
            }
        }
Esempio n. 7
0
        void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine <DkmEvaluationEnumAsyncResult> completionRoutine)
        {
            var enumContextDataItem = enumContext.GetDataItem <EnumContextDataItem>();

            if (enumContextDataItem == null)
            {
                // We don't know about this result.  Call next implementation
                enumContext.GetItems(workList, startIndex, count, completionRoutine);
                return;
            }

            var evaluationResult = enumContextDataItem.Result;
            var dataItem         = evaluationResult.GetDataItem <EvalResultDataItem>();
            var expansion        = dataItem.Expansion;

            if (expansion == null)
            {
                completionRoutine(new DkmEvaluationEnumAsyncResult(new DkmEvaluationResult[0]));
                return;
            }

            var inspectionContext = enumContext.InspectionContext;

            var rows = ArrayBuilder <EvalResult> .GetInstance();

            int index = 0;

            expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, startIndex, count, visitAll: false, index: ref index);
            var numRows = rows.Count;

            Debug.Assert(count >= numRows);
            var results = new DkmEvaluationResult[numRows];
            CompletionRoutine <Exception> onException = e => completionRoutine(DkmEvaluationEnumAsyncResult.CreateErrorResult(e));
            var wl = new WorkList(workList, onException);

            wl.ContinueWith(() =>
                            GetEvaluationResultsAndContinue(evaluationResult, rows, results, 0, numRows, wl, inspectionContext,
                                                            () =>
                                                            wl.ContinueWith(
                                                                () =>
            {
                completionRoutine(new DkmEvaluationEnumAsyncResult(results));
                rows.Free();
            }),
                                                            onException));
        }
Esempio n. 8
0
        void IDkmClrResultProvider.GetResult(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmInspectionContext inspectionContext, ReadOnlyCollection <string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine <DkmEvaluationAsyncResult> completionRoutine)
        {
            // TODO: Use full name
            var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationAsyncResult.CreateErrorResult(e)));

            GetRootResultAndContinue(
                value,
                wl,
                declaredType,
                inspectionContext,
                resultName,
                result => wl.ContinueWith(() => completionRoutine(new DkmEvaluationAsyncResult(result))));
            wl.Execute();
        }
 void IDkmClrResultProvider.GetResult(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     // TODO: Use full name
     var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationAsyncResult.CreateErrorResult(e)));
     GetRootResultAndContinue(
         value,
         wl,
         declaredType,
         declaredTypeInfo,
         inspectionContext,
         resultName,
         result => wl.ContinueWith(() => completionRoutine(new DkmEvaluationAsyncResult(result))));
     wl.Execute();
 }
Esempio n. 10
0
 private void GetEvaluationResultsAndContinue(ArrayBuilder <EvalResultDataItem> rows, DkmEvaluationResult[] results, int index, int numRows, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine completionRoutine)
 {
     if (index < numRows)
     {
         CreateEvaluationResultAndContinue(rows[index], workList, inspectionContext, stackFrame,
                                           result => workList.ContinueWith(
                                               () =>
         {
             results[index] = result;
             GetEvaluationResultsAndContinue(rows, results, index + 1, numRows, workList, inspectionContext, stackFrame, completionRoutine);
         }));
     }
     else
     {
         completionRoutine();
     }
 }
Esempio n. 11
0
        private void GetEvaluationResultsAndContinue(
            DkmEvaluationResult parent,
            ArrayBuilder <EvalResult> rows,
            DkmEvaluationResult[] results,
            int index,
            int numRows,
            WorkList workList,
            DkmInspectionContext inspectionContext,
            CompletionRoutine onCompleted,
            CompletionRoutine <Exception> onException)
        {
            DkmCompletionRoutine <DkmEvaluationAsyncResult> completionRoutine =
                result =>
            {
                try
                {
                    results[index] = result.Result;
                    GetEvaluationResultsAndContinue(parent, rows, results, index + 1, numRows, workList, inspectionContext, onCompleted, onException);
                }
                catch (Exception e)
                {
                    onException(e);
                }
            };

            if (index < numRows)
            {
                GetChild(
                    parent,
                    workList,
                    rows[index],
                    child => workList.ContinueWith(() => completionRoutine(child)));
            }
            else
            {
                onCompleted();
            }
        }
 private void GetChildrenAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, DkmStackWalkFrame stackFrame, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
 {
     var expansion = dataItem.Expansion;
     var rows = ArrayBuilder<EvalResultDataItem>.GetInstance();
     int index = 0;
     if (expansion != null)
     {
         expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, 0, initialRequestSize, visitAll: true, index: ref index);
     }
     var numRows = rows.Count;
     Debug.Assert(index >= numRows);
     Debug.Assert(initialRequestSize >= numRows);
     var initialChildren = new DkmEvaluationResult[numRows];
     var wl = new WorkList(workList, e => completionRoutine(DkmGetChildrenAsyncResult.CreateErrorResult(e)));
     GetEvaluationResultsAndContinue(rows, initialChildren, 0, numRows, wl, inspectionContext, stackFrame,
         () => wl.ContinueWith(
             () =>
             {
                 var enumContext = DkmEvaluationResultEnumContext.Create(index, stackFrame, inspectionContext, new EnumContextDataItem(dataItem));
                 completionRoutine(new DkmGetChildrenAsyncResult(initialChildren, enumContext));
                 rows.Free();
             }));
     wl.Execute();
 }
Esempio n. 13
0
 private void GetChild(
     DkmEvaluationResult parent,
     WorkList workList,
     EvalResult row,
     DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     var inspectionContext = row.InspectionContext;
     if ((row.Kind != ExpansionKind.Default) || (row.Value == null))
     {
         CreateEvaluationResultAndContinue(
             row,
             workList,
             row.InspectionContext,
             parent.StackFrame,
             child => completionRoutine(new DkmEvaluationAsyncResult(child)));
     }
     else
     {
         var typeDeclaringMember = row.TypeDeclaringMemberAndInfo;
         var name = (typeDeclaringMember.Type == null) ?
             row.Name :
             GetQualifiedMemberName(row.InspectionContext, typeDeclaringMember, row.Name, FullNameProvider);
         row.Value.GetResult(
             workList.InnerWorkList,
             row.DeclaredTypeAndInfo.ClrType,
             row.DeclaredTypeAndInfo.Info,
             row.InspectionContext,
             Formatter.NoFormatSpecifiers,
             name,
             row.FullName,
             result => workList.ContinueWith(() => completionRoutine(result)));
     }
 }
Esempio n. 14
0
        private void GetResultAndContinue(
            EvalResult result,
            WorkList workList,
            DkmClrType declaredType,
            DkmClrCustomTypeInfo declaredTypeInfo,
            DkmInspectionContext inspectionContext,
            bool useDebuggerDisplay,
            CompletionRoutine <DkmEvaluationResult> completionRoutine)
        {
            var value = result.Value; // Value may have been replaced (specifically, for Nullable<T>).
            DebuggerDisplayInfo displayInfo;

            if (value.TryGetDebuggerDisplayInfo(out displayInfo))
            {
                var targetType = displayInfo.TargetType;
                var attribute  = displayInfo.Attribute;
                CompletionRoutine <Exception> onException =
                    e => completionRoutine(CreateEvaluationResultFromException(e, result, inspectionContext));

                var innerWorkList = workList.InnerWorkList;
                EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Name,
                                                         displayName => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Value,
                                                                                                                 displayValue => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.TypeName,
                                                                                                                                                                          displayType =>
                                                                                                                                                                          workList.ContinueWith(() =>
                                                                                                                                                                                                completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName.Result, displayValue.Result, displayType.Result, useDebuggerDisplay))),
                                                                                                                                                                          onException),
                                                                                                                 onException),
                                                         onException);
            }
            else
            {
                completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName: null, displayValue: null, displayType: null, useDebuggerDisplay: false));
            }
        }
Esempio n. 15
0
        private void GetResultAndContinue(
            EvalResult result,
            WorkList workList,
            DkmClrType declaredType,
            DkmClrCustomTypeInfo declaredTypeInfo,
            DkmInspectionContext inspectionContext,
            bool useDebuggerDisplay,
            CompletionRoutine<DkmEvaluationResult> completionRoutine)
        {
            var value = result.Value; // Value may have been replaced (specifically, for Nullable<T>).
            DebuggerDisplayInfo displayInfo;
            if (value.TryGetDebuggerDisplayInfo(out displayInfo))
            {
                var targetType = displayInfo.TargetType;
                var attribute = displayInfo.Attribute;
                CompletionRoutine<Exception> onException =
                    e => completionRoutine(CreateEvaluationResultFromException(e, result, inspectionContext));

                var innerWorkList = workList.InnerWorkList;
                EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Name,
                    displayName => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Value,
                        displayValue => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.TypeName,
                            displayType =>
                                workList.ContinueWith(() =>
                                    completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName.Result, displayValue.Result, displayType.Result, useDebuggerDisplay))),
                            onException),
                        onException),
                    onException);
            }
            else
            {
                completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName: null, displayValue: null, displayType: null, useDebuggerDisplay: false));
            }
        }
Esempio n. 16
0
 private void GetEvaluationResultsAndContinue(
     DkmEvaluationResult parent,
     ArrayBuilder<EvalResult> rows,
     DkmEvaluationResult[] results,
     int index,
     int numRows,
     WorkList workList,
     DkmInspectionContext inspectionContext,
     CompletionRoutine onCompleted,
     CompletionRoutine<Exception> onException)
 {
     DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine =
         result =>
         {
             try
             {
                 results[index] = result.Result;
                 GetEvaluationResultsAndContinue(parent, rows, results, index + 1, numRows, workList, inspectionContext, onCompleted, onException);
             }
             catch (Exception e)
             {
                 onException(e);
             }
         };
     if (index < numRows)
     {
         GetChild(
             parent,
             workList,
             rows[index],
             child => workList.ContinueWith(() => completionRoutine(child)));
     }
     else
     {
         onCompleted();
     }
 }
 private void GetItemsAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, int startIndex, int count, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
 {
     var expansion = dataItem.Expansion;
     var value = dataItem.Value;
     var rows = ArrayBuilder<EvalResultDataItem>.GetInstance();
     if (expansion != null)
     {
         int index = 0;
         expansion.GetRows(this, rows, inspectionContext, dataItem, value, startIndex, count, visitAll: false, index: ref index);
     }
     var numRows = rows.Count;
     Debug.Assert(count >= numRows);
     var results = new DkmEvaluationResult[numRows];
     var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationEnumAsyncResult.CreateErrorResult(e)));
     GetEvaluationResultsAndContinue(rows, results, 0, numRows, wl, inspectionContext, value.StackFrame,
         () => wl.ContinueWith(
             () =>
             {
                 completionRoutine(new DkmEvaluationEnumAsyncResult(results));
                 rows.Free();
             }));
     wl.Execute();
 }
Esempio n. 18
0
        void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
        {
            var enumContextDataItem = enumContext.GetDataItem<EnumContextDataItem>();
            if (enumContextDataItem == null)
            {
                // We don't know about this result.  Call next implementation
                enumContext.GetItems(workList, startIndex, count, completionRoutine);
                return;
            }

            var evaluationResult = enumContextDataItem.Result;
            var dataItem = evaluationResult.GetDataItem<EvalResultDataItem>();
            var expansion = dataItem.Expansion;
            if (expansion == null)
            {
                completionRoutine(new DkmEvaluationEnumAsyncResult(new DkmEvaluationResult[0]));
                return;
            }

            var inspectionContext = enumContext.InspectionContext;

            var rows = ArrayBuilder<EvalResult>.GetInstance();
            int index = 0;
            expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, startIndex, count, visitAll: false, index: ref index);
            var numRows = rows.Count;
            Debug.Assert(count >= numRows);
            var results = new DkmEvaluationResult[numRows];
            CompletionRoutine<Exception> onException = e => completionRoutine(DkmEvaluationEnumAsyncResult.CreateErrorResult(e));
            var wl = new WorkList(workList, onException);
            wl.ContinueWith(() =>
                GetEvaluationResultsAndContinue(evaluationResult, rows, results, 0, numRows, wl, inspectionContext,
                    () =>
                    wl.ContinueWith(
                        () =>
                        {
                            completionRoutine(new DkmEvaluationEnumAsyncResult(results));
                            rows.Free();
                        }),
                    onException));
        }
 private void GetEvaluationResultsAndContinue(ArrayBuilder<EvalResultDataItem> rows, DkmEvaluationResult[] results, int index, int numRows, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine completionRoutine)
 {
     if (index < numRows)
     {
         CreateEvaluationResultAndContinue(rows[index], workList, inspectionContext, stackFrame,
             result => workList.ContinueWith(
                 () =>
                 {
                     results[index] = result;
                     GetEvaluationResultsAndContinue(rows, results, index + 1, numRows, workList, inspectionContext, stackFrame, completionRoutine);
                 }));
     }
     else
     {
         completionRoutine();
     }
 }
Esempio n. 20
0
        void IDkmClrResultProvider.GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
        {
            var dataItem = evaluationResult.GetDataItem<EvalResultDataItem>();
            if (dataItem == null)
            {
                // We don't know about this result.  Call next implementation
                evaluationResult.GetChildren(workList, initialRequestSize, inspectionContext, completionRoutine);
                return;
            }

            var expansion = dataItem.Expansion;
            if (expansion == null)
            {
                var enumContext = DkmEvaluationResultEnumContext.Create(0, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult));
                completionRoutine(new DkmGetChildrenAsyncResult(new DkmEvaluationResult[0], enumContext));
                return;
            }

            // Evaluate children with InspectionContext that is not the root.
            inspectionContext = inspectionContext.With(NotRoot);

            var rows = ArrayBuilder<EvalResult>.GetInstance();
            int index = 0;
            expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, 0, initialRequestSize, visitAll: true, index: ref index);
            var numRows = rows.Count;
            Debug.Assert(index >= numRows);
            Debug.Assert(initialRequestSize >= numRows);
            var initialChildren = new DkmEvaluationResult[numRows];
            CompletionRoutine<Exception> onException = e => completionRoutine(DkmGetChildrenAsyncResult.CreateErrorResult(e));
            var wl = new WorkList(workList, onException);
            wl.ContinueWith(() =>
                GetEvaluationResultsAndContinue(evaluationResult, rows, initialChildren, 0, numRows, wl, inspectionContext,
                    () =>
                    wl.ContinueWith(
                        () =>
                        {
                            var enumContext = DkmEvaluationResultEnumContext.Create(index, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult));
                            completionRoutine(new DkmGetChildrenAsyncResult(initialChildren, enumContext));
                            rows.Free();
                        }),
                    onException));
        }