Skip to content

Latest commit

 

History

History
82 lines (62 loc) · 5.54 KB

File metadata and controls

82 lines (62 loc) · 5.54 KB

PX1008

This document describes the PX1008 diagnostic.

Summary

Code Short Description Type Code Fix
PX1008 The reference to the screen graph or an action adapter in the long-running operation and processing delegates causes synchronous execution of the delegate. Error Unavailable

Diagnostic Description

The delegates passed to the PXLongOperation, ILongOperationManager, and IGraphLongOperationManager APIs that start long-running operations should not contain references to the screen graph or an action adapter of the PXAdapter type from the graph action delegate's parameters because such references cause synchronous execution of the long-running operation. Long-running operations are started by the following APIs:

  • The PXLongOperation.StartOperation methods
  • The ILongOperationManager.StartOperation, ILongOperationManager.StartAsyncOperation, and ILongOperationManager.Await methods
  • The IGraphLongOperationManager.StartOperation and IGraphLongOperationManager.StartAsyncOperation methods

The same rule applies to the delegates passed to the SetProcessDelegate and SetAsyncProcessDelegate methods of the PXProcessingBase<Table> class and its inheritors. Such classes represent processing graph views in Acumatica Framework. These delegates are called processing delegates and they should not contain references to the screen graph or an action PXAdapter adapter from parameters of the graph action delegate in the delegate closure.

The PX1008 diagnostic validates delegates passed to the methods listed above and finds references to an instance of a screen graph and action adapters captured by the delegate closures.

The diagnostic uses data flow analysis that considers the passed data. This allows the diagnostic to check the parameters passed to other graph and helper methods. For example, if a developer passes a screen graph or an action adapter as an argument to a method and invokes in this method a long-running operation that uses the passed arguments, this diagnostic captures such code. Corner cases not captured by the data flow analysis exist because live diagnostics have to limit resource usage and some things cannot be checked at compile time. But in our practice, these cases are rarely encountered in the production code.

To fix the issue, you rewrite the delegate so that it does not contain references to the screen graph or the action adapter.

Example of Code That Results in the Warning

public class SomeGraph : PXGraph<SomeGraph>
{
	public PXFilteredProcessing<SomeDAC> Processing;
  
	public SomeGraph()
	{
		Processing.SetProcessDelegate(item => this.Process(item)); // The PX1008 error is displayed for this line.
	}
  
	private Process(SomeDAC item) { }
}

Example of the Data Flow Analysis That Captures Helper Methods

Suppose that a helper class contains the following methods:

  • CaptureInLongRun which initiates a long-running operation with a graph instance in the delegate
  • CaptureInLongRunArray which initiates a long-running operation that captures the array of objects passed to it in the delegate

The diagnostic will show a warning, as shown in the following code.

public IEnumerable someAction(PXAdapter adapter)
{
	var helper = new NonGraph();
	helper.CaptureInLongRun(this);                      // The PX1008 error is displayed for this line.
	helper.CaptureInLongRunArray(new[] { adapter });    // The PX1008 error is displayed for this line.

	return adapter.Get();
}

Principles of the Data Flow Analysis

The following section describes the principles of the data flow analysis used by the analyzer of the PX1008 diagnostic. The analyzer maintains a stack of non-capturable elements. Before the analyzer visits a method from a method call recursively, the analyzer calculates the entity that can capture a reference to a graph or an adapter at the call site. The diagnostic supports the following situations:

  • When the analyzer is at the top of the call stack and inside an action handler. In this case, the adapter parameter can be captured.
  • When the analyzer is inside a graph or a graph extension and this is passed among the arguments.
  • When the analyzer is inside a recursive call and already has some non-capturable parameters that are used in call arguments.
  • When the analyzer is inside a local method and parameters from containing methods have some non-capturable elements.

Additional analysis performs the following checks:

  • Checks for parameters and this captured in arguments expression
  • Checks for reassignments of parameters before the call site

Related Articles