Simon Nicholls
Simon Nicholls

Reputation: 655

Updating a UI component using Invoke Async Deadlock

I am using devexpress and their PivotGrid control to build a pivot grid. I don't care about displaying it I have no actual UI displayed, I want the PivotGrid so I can export it.

Therefore I am creating and updating the pivot grid object on a separate STA thread else it won't work. I execute the method that handles the retrieving of data through the following code:

 PivotGridControl pivotGrid = null;
 Thread thread = new Thread(() => { pivotGrid = _reportProcessor.RunReport(currentReport.ReportId).Result; });
 thread.SetApartmentState(ApartmentState.STA);
 thread.Start();
 thread.Join();

The part of the RunReport method that isn't working is the following:

 public async Task<PivotGridControl> RunReport(int reportId)
    {
        //var pivotGrid = new PivotGridFactory().GetPivotGrid();

        var pivotGrid = new PivotGridControl();

        //Get report info
        var report = await _reportReferenceService.GetReportReference(reportId);

        //Get data definition
        var dataDefinition = await _reportDataDefService.GetDataDefinition(report.DataDefinitionId);

        //Get fields
        var fields = await _reportFieldService.GetFields(FieldSetId);

        //Get layout
        var layout = await _reportLayoutService.GetLayout(report.LayoutId);
        var layoutStream = StreamUtils.StringToStream(layout.Definition);
        var collapseStream = StreamUtils.Base64StringToStream(layout.CollapseState);
        await pivotGrid.Dispatcher.InvokeAsync(delegate
        {
            pivotGrid.BeginUpdate();
            pivotGrid.Fields.Clear();
            pivotGrid.Fields.Where(x => x.Visible).ForEach(x => x.Visible = false);
            pivotGrid.RestoreLayoutFromStream(layoutStream);
            pivotGrid.RestoreCollapsedStateFromStream(collapseStream);
            pivotGrid.AllowConditionalFormattingMenu = true;
            pivotGrid.AllowConditionalFormattingManager = true;
            pivotGrid.EndUpdate();
        });

        //Get field spec
        var fieldSpec = _reportFieldService.GetFieldSpecification(pivotGrid.Fields);

        //Get report data 
        var reportData = await _reportDataService.GetReportData(fieldSpec, dataDefinition.FundDataSpecification, dataDefinition.DifferenceSpecification, dataDefinition.TimeSeriesSpecification, dataDefinition.RiskDataSpecification, null);

        //Set pivot data
        pivotGrid.BeginUpdate();
        pivotGrid.DataSource = reportData;
        pivotGrid.EndUpdate();

        return pivotGrid;

    }

As it is this locks and the delegate is never run, I'm assuming there is a deadlock somewhere but I'm surprised the delegate isn't run at all.

Upvotes: 0

Views: 124

Answers (0)

Related Questions