-1

I am printing a pdf using the PrintAsync() function of a WebView2 controller. This pdf is being prepared behind the scenes, so the user might ask to print it before it is ready. For this scenario, I have hooked an event that fires when the async Task of the pdf being prepared finishes.

The following code is called in the UI to print the after the pdf is ready, but because it might be called from the other thread that fires the event, it must be invoked via the dispatcher. This seems to be working when called from the UI itself (i.e. if the pdf is already ready when the user clicks the button) but not when called from the event handler (PrintAsync returns in a split second and results in an empty 1-page pdf).

I have tried two versions after some googling:

//Version 1 with InvokeAsync and unwrapping.
private async Task printAll()
{
    CoreWebView2PrintStatus printStatus = CoreWebView2PrintStatus.OtherError;

    printStatus = await Dispatcher.InvokeAsync(async () =>
    {
        dummyWebView.Source = m_viewModel.renderedPdfForAllCalculations;
        return await dummyWebView.CoreWebView2.PrintAsync(m_printAllPrintSettings);
    }).Task.Unwrap();
    
    if (printStatus != CoreWebView2PrintStatus.Succeeded)
    {
        // show message
    }
}

// Version 2 with Invoke. In this scenario, PrintAsync returns almost immediately and results in an empty 1-page pdf.
private async Task printAll()
{
    CoreWebView2PrintStatus printStatus = CoreWebView2PrintStatus.OtherError;

    await Dispatcher.Invoke(async () =>
    {
        dummyWebView.Source = m_viewModel.renderedPdfForAllCalculations;
        printStatus = await dummyWebView.CoreWebView2.PrintAsync(m_printAllPrintSettings);
    });
    
    if (printStatus != CoreWebView2PrintStatus.Succeeded)
    {
        // show message
    }
}
Tsaras
  • 455
  • 2
  • 4
  • 18
  • I'm not sure if it's required, but you can use `CheckAccess` on the `Dispatcher` to see if `Invoke` is necessary. https://stackoverflow.com/questions/15504826/invokerequired-in-wpf – bigcrazyal Jun 19 '23 at 15:56
  • I think the problem is that the PrintAsync() function is called within the Dispatcher and something goes wrong there, although I cannot find what. If I call that outside the Dispatcher, I do not get an exception on the dummyWebView control like I normally would, but it does not do its job properly. – Tsaras Jun 20 '23 at 10:35

2 Answers2

0

It sounds like it needs to be invoked on the UI thread. I have had success with a similar situation by injecting the dispatcher for the UI thread into the objects that need to do things on the UI thread.

Instantiated (on main thread) like this:

private readonly Dispatcher _dispatcher = Dispatcher.CurrentDispatcher;

Invoked like this:

_mainDispatcher.Invoke((Action)delegate
{

        // Do the stuff on the main thread

});
Peter Dongan
  • 1,762
  • 12
  • 17
0

Use an overload of the Dispatcher.Invoke method that accepts a Task<T>:

printStatus = await Dispatcher.Invoke<Task<CoreWebView2PrintStatus>>(async () =>
{
    dummyWebView.Source = m_viewModel.renderedPdfForAllCalculations;
    return await dummyWebView.CoreWebView2.PrintAsync(m_printAllPrintSettings);
});
mm8
  • 163,881
  • 10
  • 57
  • 88
  • This has the same result as my examples. What happens is that PrintAsync is somehow run (printStatus is changed to Succeeded) but completes in a split second and it only prints an empty 1-page pdf instead of the actual document. If I click the button when the pdf is ready, thus running this function from the UI itself, the printing works normally. – Tsaras Jun 22 '23 at 13:15
  • So the `PrintAsync` method is now awaited as expected and the scenario of "nothing is awaited and the function continues execution almost immediately" has been solved? Or where do you get the return value from? Do you set the `Source` immediately before you call `PrintAsync` in the working case? – mm8 Jun 22 '23 at 14:42
  • This was the original behavior which I had not done a good job explaining. I have edited my post with a more precise explanation. To me it seems like there is some kind of issue with the WebView2 control when printing in this specific scenario. If I call the same function from the button click it works, but if the threaded event fires I always get an empty document after printing. – Tsaras Jun 23 '23 at 08:57