-1

I have a problem where it takes a few seconds to generate a report and send it to the printer (creating the RDLC report container is slow).

To make sure the user is aware of what is going on I attempted to update a status line before and after doing the print//.

Status = "Printing Report.";
OnPropertyChanged("Status");
//Create a hidden window to host the report control
ReportWindow rw = new ReportWindow();
rw.PrintReport();
rw.Close();  
Status = "Printing Report complete.";
OnPropertyChanged("Status");

What I wanted to happen was:

  1. Status is updated indicating that the report is being created and will be printed as soon as its done.
  2. The report is created and printed over several seconds.
  3. Status is updated to show success.

What actually happens is:

  1. Nothing is shown on the UI
  2. After a few seconds, the report is created and printed
  3. Status is updated indicating that the report is being created and will be printed as soon as its done.
  4. Immediately afterwards status is updated to show success. This happens fast enough that the first message is at most strobed on the screen for a single screen refresh; at worst it's never seen at all unless I interrupt with a break point.

I've had similar issues before with WPF prioritizing doing something slow on the UI thread above updating the UI to indicate that it's going to be busy for a few seconds; but in this case I'm not able to remove the heavy item from the UI thread (or do something else) to avoid the issue.

  • 3
    Don't do long running non-UI actions in the UI thread if you want the UI thread to be able to actually perform UI actions. – Servy Mar 13 '17 at 16:02
  • Check out this link for adding a "Refresh" extension method so that your controls can be updated immediately : http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx. Note one of the comments below the main article (dated Sep 24, 2009) about possibly needing to adjust the priority to get the response you need. – PaulF Mar 13 '17 at 16:10
  • @Servy see my comment on MikeT's answer for a little more detail, what's consuming all the time is creating a UI element and that needs to be done on the UI thread. – Dan Is Fiddling By Firelight Mar 13 '17 at 16:58
  • Can we see the code for the ReportWindow? – Brandon Kramer Mar 13 '17 at 17:53
  • @MikeT Why did you delete your answer? I saw an edit intended to address my problem with the UI control loading slowly and then a few minutes later you deleted it entirely. – Dan Is Fiddling By Firelight Mar 13 '17 at 18:05

1 Answers1

0

... but in this case I'm not able to remove the heavy item from the UI thread (or do something else) to avoid the issue

In this case you could create a new window that launches in a separate thread and display this one while the report is printing:

Wait screen during rendering UIElement in WPF

Once the report has been printed you just close the new window:

Window tempWindow = null;
Thread newWindowThread = new Thread(new ThreadStart(() =>
{
    SynchronizationContext.SetSynchronizationContext(
    new DispatcherSynchronizationContext(
        Dispatcher.CurrentDispatcher));

    tempWindow = new Window();
    tempWindow.Content = new ProgressBar() { IsIndeterminate = true };
    tempWindow.Closed += (ss, ee) =>
    Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);

    tempWindow.Show();
    System.Windows.Threading.Dispatcher.Run();
}));

newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();

ReportWindow rw = new ReportWindow();
rw.PrintReport();
rw.Close();

if (tempWindow != null)
    tempWindow.Dispatcher.Invoke(new Action(() => tempWindow.Close())); 
Community
  • 1
  • 1
mm8
  • 163,881
  • 10
  • 57
  • 88
  • should `tempWindow = new Window1();` be `tempWindow = new ReportWindow();`? If not, where do I inject my window into the setup you're doing? – Dan Is Fiddling By Firelight Mar 13 '17 at 18:36
  • No, it should be new Window(). This is just a window with a ProgressBar that gets displayed on another thread during the time it takes for your code on the main UI thread to complete. – mm8 Mar 13 '17 at 18:40