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
- Treat PrintingCanceledException as an expected outcome: catch it in the code that streams to the printer and skip further writes
- Check PrintQueue.PrintingIsCancelled before each write or before BeginWrite and stop the loop gracefully
- Use the stream's Abort/Close path instead of writing after cancellation has been requested
- 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
- Check PrintingIsCancelled before every write in the print loop
- Keep one owner of the job lifecycle so Abort and writes are serialized
- Treat PrintingCanceledException as control flow, not failure
- Log cancellation HRESULTs separately from real spooler errors
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
- ArgumentException.NonNegativeValue (Parameter 'squareScale')
- ArgumentException.PositiveValue (Parameter 'value')
- ArgumentException.PositiveValue (Parameter 'value')
- errMsg (dynamic: message of caught…
- getPage
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)