Skip to main content

Context Walkthrough

SAL code can refer to a current window or bind variable without passing every owner explicitly. Generated PPJ code preserves that behavior with scoped context objects. The important operation is restore the previous context, rather than reset everything to a single global default.

Context entry, nesting, and restoration
  1. Form AOuter visual contextActive
  2. Form BNested visual context
  3. SQL scopeOwner + extracted locals
  4. CallerPrior context restored
Step 1 of 6Enter Form A

A generated visual method establishes SalContext(A). SAL window variables now describe this context.

SAL top: A · SQL top: previous

A conceptual sequence, not a live runtime trace. Playback advances every four seconds. The full explanation follows below.

Follow a Normal Call

Imagine Form A calls Form B, and B performs a query using extracted local variables.

StepActive SAL contextActive SQL contextWhat happens
Enter AAPreviousA's generated SalContext establishes its window context.
Enter BB, with A beneath itPreviousB's method establishes a nested visual scope.
Enter SQL scopeBB + localsSqlContext(locals, this) provides the object and extracted variables used for SQL symbol resolution.
Leave SQL scopeBPreviousDisposal restores the preceding SQL context.
Return from BAPreviousDisposal restores A's window context.
Return from APreviousPreviousThe caller's original context is restored.

This is a logical stack diagram. The runtime can optimize repeated entry into the same context; the diagram does not promise one allocation or physical push for every call.

Exception Unwinding

C# using guarantees disposal when execution leaves the scope normally or through an exception. In the nested example, the SQL scope exits first. If the exception continues out of B, B's SAL scope exits next. A can catch the exception inside its own context; if the exception leaves that block too, A's context is restored to its predecessor.

// Scope structure only: QueryWithLocals represents application code.
using (new SalContext(this))
{
using (new SqlContext(locals, this))
{
QueryWithLocals();
}
}

Disposing SqlContext is not a transaction commit, rollback, or SQL-handle disconnect. It restores name-resolution context. Database transaction and connection ownership remain separate responsibilities.

What the Context Means

SalContext supports SAL window variables such as hWndForm, hWndItem, and hWndMDI. These are not interchangeable with this: a control, its form, and the source of a call can differ. SQL binding also uses the active context to find symbols.

SqlContext exposes the current owner and extracted local variables for binding. The SQL resolver consults this context and the active SAL context. A helper that runs successfully when called from one form can resolve differently when called from another if its necessary scope was removed.

Refactoring and Asynchronous Work

Keep context-dependent work within the generated synchronous scope until tests establish an equivalent design. Passing an object reference to a worker does not transfer the surrounding context stack, a UI thread, or a web session. Likewise, do not infer that context automatically flows across await from the fact that C# keeps the using object alive.

For background work, pass explicit immutable inputs where possible. Establish the installed target's supported session/UI execution context when updating the application, and establish SQL context where binding actually happens. Do not reuse one context object concurrently.

Verify a Change

  1. Log the expected window identity in A, then in B, then after returning to A. Confirm the original identity is restored.
  2. Give A and B different values for a similarly named bind variable. Verify the query resolves the intended owner and local value.
  3. Throw inside B's SQL scope; catch in A and verify both context restoration and independent transaction cleanup.
  4. Repeat the test from a control event and, for Web, from separate sessions. A single happy-path form call does not cover those entry paths.

See the detailed SalContext and SqlContext chapters, and Microsoft's using statement reference.