How to correctly cancel a printing task running on

2019-04-17 07:07发布

问题:

[Please note: This question was effectively solved in my other question: How to use a cancellationtokensource to cancel background printing]

I have been using the following method (from SO) to run my printers and print previews on a background thread:

 public static Task StartSTATask(Action func)
        {
            var tcs = new TaskCompletionSource<object>();
            var thread = new Thread(() =>
            {
                try
                {
                    func();
                    tcs.SetResult(null);
                }
                catch (Exception e)
                {
                    tcs.SetException(e);
                }
            });
            thread.SetApartmentState(ApartmentState.STA);

            thread.Priority = ThreadPriority.AboveNormal;
            thread.Start();
            return tcs.Task;
        }

It works perfectly, without error.

I do not get how to cancel this task appropriately. Should I abort the thread completely or pass in a CancellationTokenSource Token? How is the above code changed to allow cancellation (or abort)?

I am very confused. Thanks for any help with this.

(After much googling, the solution here is not at all as trivial as I had hoped!)

After more thought, I am leaning toward passing the CancellationToken to the func() being executed, and force the function to terminate. In this case, that means the PrintDialogue() to close. Is there another way?

I'm using the above code as:

 public override Task PrintPreviewAsync()
    {
            return StartSTATask(() =>
            {
                // Set up the label page
                LabelMaker chartlabels =  ...

                ... create a fixed document...

                // print preview the document.
                chartlabels.PrintPreview(fixeddocument);
            });
        }

// Print Preview
    public static void PrintPreview(FixedDocument fixeddocument)
    {
        MemoryStream ms = new MemoryStream();

        using (Package p = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite))
        {
            Uri u = new Uri("pack://TemporaryPackageUri.xps");
            PackageStore.AddPackage(u, p);
            XpsDocument doc = new XpsDocument(p, CompressionOption.Maximum, u.AbsoluteUri);
                XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);

            writer.Write(fixeddocument.DocumentPaginator);

            /*  A Working Alternative without custom previewer
            //View in the DocViewer
            var previewWindow = new Window();
            var docViewer = new DocumentViewer();  //  the System.Windows.Controls.DocumentViewer class.
            previewWindow.Content = docViewer;

            FixedDocumentSequence fixedDocumentSequence = doc.GetFixedDocumentSequence();
            docViewer.Document = fixedDocumentSequence as IDocumentPaginatorSource;

            // ShowDialog - Opens a window on top and returns only when the newly opened window is closed.
            previewWindow.ShowDialog();
            */

            FixedDocumentSequence fixedDocumentSequence = doc.GetFixedDocumentSequence();

            // Use my custom document viewer (the print button is removed).
            var previewWindow = new PrintPreview(fixedDocumentSequence);
            previewWindow.ShowDialog();
            PackageStore.RemovePackage(u);
            doc.Close();
        }
    }

Hope it helps explains my problem better.