{"record":{"id":"d09391402b256621","repo":"dotnet/wpf","slug":"printsystemexception-printingcancelled-generic","errorCode":null,"errorMessage":"PrintSystemException.PrintingCancelled.Generic","messagePattern":"PrintSystemException\\.PrintingCancelled\\.Generic","errorType":"exception","errorClass":"PrintingCanceledException","httpStatus":null,"severity":"warning","filePath":"src/Microsoft.DotNet.Wpf/src/System.Printing/CPP/src/PremiumPrintStream.cpp","lineNumber":235,"sourceCode":"\nvoid\nPrintQueueStream::\nWrite(\n    array<unsigned char>^   array,\n    int                     offset,\n    int                     numBytes\n    )\n{\n    if (printerThunkHandler != nullptr)\n    {\n        if (printQueue->PrintingIsCancelled)\n        {\n\n            printerThunkHandler->ThunkAbortPrinter();\n\n            printQueue->PrintingIsCancelled = false;\n\n            throw CreatePrintingCanceledException(HRESULT_FROM_WIN32(ERROR_PRINT_CANCELLED),\n                                                  \"PrintSystemException.PrintingCancelled.Generic\");\n        }\n        else\n        {\n            //Do not write to the spoolFileStream if its aborted\n            if (!streamAborted)\n            {\n                printerThunkHandler->SpoolStream->Write(array, offset, numBytes);\n\n                //\n                // Computing the number of bytes that need to be commited to Spooler\n                // when the FixedPageAdded notification comes in.\n                //\n                if (!commitStreamDataOnClose)\n                {\n                    bytesToCommit += numBytes;\n                }\n            }","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/System.Printing/CPP/src/PremiumPrintStream.cpp#L217-L253","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\nstream.BeginWrite(buffer, 0, buffer.Length, callback, state);\n// after\nif (printQueue.PrintingIsCancelled) return; // stop gracefully\ntry { stream.BeginWrite(buffer, 0, buffer.Length, callback, state); }\ncatch (PrintingCanceledException) { /* user cancelled; stop writing */ }","handlingStrategy":"try-catch","validationCode":"if (printQueue == null) throw new InvalidOperationException(\"No print queue\");\nif (printQueue.PrintingIsCancelled) return; // skip write entirely","typeGuard":"static bool IsCancelled(PrintQueue q) => q?.PrintingIsCancelled == true;","tryCatchPattern":"try { stream.BeginWrite(buffer, 0, len, cb, state); }\ncatch (PrintSystemException ex) when (ex.Message.Contains(\"PrintingCancelled\")) { /* treat as user cancel; stop */ }","preventionTips":["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"],"tags":["wpf","printing","cancellation"],"backgroundTag":"print-job-cancelled","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}