dotnet/wpf · warning · PrintingCanceledException

PrintSystemException.PrintingCancelled.Generic

Error message

PrintSystemException.PrintingCancelled.Generic

What it means

This is a WPF System.Printing cancellation error thrown when the print queue reports that printing was cancelled (PrintingIsCancelled is true) during an asynchronous BeginWrite/Write operation on the PrintQueueStream. The library wraps Win32 ERROR_PRINT_CANCELLED in a PrintingCanceledException so callers can distinguish user/system cancellation from real failures. It is not a bug; it signals the print job was aborted before the bytes were submitted to the spooler.

Solutions

  1. Treat PrintingCanceledException as an expected outcome: catch it in the code that streams to the printer and skip further writes
  2. Check PrintQueue.PrintingIsCancelled before each write or before BeginWrite and stop the loop gracefully
  3. Use the stream's Abort/Close path instead of writing after cancellation has been requested
  4. If cancellation is unexpected, verify the job id is still valid and that nothing else deletes the job (e.g. another thread or the print UI)

Example fix

// before
stream.BeginWrite(buffer, 0, buffer.Length, callback, state);
// after
if (printQueue.PrintingIsCancelled) return; // stop gracefully
try { stream.BeginWrite(buffer, 0, buffer.Length, callback, state); }
catch (PrintingCanceledException) { /* user cancelled; stop writing */ }
Defensive patterns

Strategy: try-catch

Validate before calling

if (printQueue == null) throw new InvalidOperationException("No print queue");
if (printQueue.PrintingIsCancelled) return; // skip write entirely

Type guard

static bool IsCancelled(PrintQueue q) => q?.PrintingIsCancelled == true;

Try / catch

try { stream.BeginWrite(buffer, 0, len, cb, state); }
catch (PrintSystemException ex) when (ex.Message.Contains("PrintingCancelled")) { /* treat as user cancel; stop */ }

Prevention

When it happens

Trigger: Calling PrintQueueStream.BeginWrite (or Write) after PrintQueue.PrintingIsCancelled has been set true, e.g. because the user cancelled the job from the print UI or Abort was called on the stream.

Common situations: User hits Cancel in the printer progress dialog while an XPS document is being streamed to the spooler; application calls Abort on the PrintQueueStream while a write is in flight; a print job is deleted from the queue mid-print.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/d09391402b256621. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Printing/CPP/src/PremiumPrintStream.cpp:235

void
PrintQueueStream::
Write(
    array<unsigned char>^   array,
    int                     offset,
    int                     numBytes
    )
{
    if (printerThunkHandler != nullptr)
    {
        if (printQueue->PrintingIsCancelled)
        {

            printerThunkHandler->ThunkAbortPrinter();

            printQueue->PrintingIsCancelled = false;

            throw CreatePrintingCanceledException(HRESULT_FROM_WIN32(ERROR_PRINT_CANCELLED),
                                                  "PrintSystemException.PrintingCancelled.Generic");
        }
        else
        {
            //Do not write to the spoolFileStream if its aborted
            if (!streamAborted)
            {
                printerThunkHandler->SpoolStream->Write(array, offset, numBytes);

                //
                // Computing the number of bytes that need to be commited to Spooler
                // when the FixedPageAdded notification comes in.
                //
                if (!commitStreamDataOnClose)
                {
                    bytesToCommit += numBytes;
                }
            }

View on GitHub (pinned to 81131a70a4)