This is a migrated thread and some comments may be shown as answers.

PdfViewer doesn't load from stream if called after loading from a path

7 Answers 940 Views
PdfViewer and PdfViewerNavigator
This is a migrated thread and some comments may be shown as answers.
Phil
Top achievements
Rank 1
Phil asked on 07 Jun 2017, 06:24 AM

I have an application with multiple PDF viewers and the user can switch between the viewers on demand.

When switching between viewers I do the following:

  • Reset the viewer by displaying a dummy document (so that the previous PDF is no longer visible and so that a template, etc. could be displayed as a placeholder if something goes wrong - previous developer's choice). This is done by calling LoadDocument() with the placeholder's physical file path
  • I then do a bunch of things and get the new desired content as a MemoryStream from the database and load it. This is done by calling LoadDocument() with the MemoryStream variable

When this happens, the content of the MemoryStream is not displayed, instead only the placeholder content is shown. It's as though the load of the MemoryStream was never loaded (but I have confirmed that line of code is always reached).

If I remove the placeholder code so that I'm only working with a MemoryStream then it works correctly.

Calling UnloadDocument() before loading from the MemoryStream has no effect.

What can be done to fix this?

7 Answers, 1 is accepted

Sort by
0
Dimitar
Telerik team
answered on 08 Jun 2017, 10:50 AM
Hello Phil,

Thank you for writing.

The documents are loaded on a separate thread. So you need to make sure that the first document is loaded before loading the second one. For example:
public RadForm1()
{
    InitializeComponent();
    radPdfViewer1.DocumentLoaded += RadPdfViewer1_DocumentLoaded;
}
 
bool stopLoad;
 
 
private void radButton1_Click(object sender, EventArgs e)
{
    stopLoad = true;
    radPdfViewer1.LoadDocument(@"C:\Users\dkaramfi\Desktop\test.pdf");
    while (stopLoad)
    {
        Thread.Sleep(300);
        Application.DoEvents();
 
    }
 
    FileStream fs = new FileStream(@"C:\Users\dkaramfi\Desktop\test2.pdf", FileMode.Open);
    radPdfViewer1.LoadDocument(fs);
 
}
private void RadPdfViewer1_DocumentLoaded(object sender, EventArgs e)
{
    stopLoad = false;
}

Let me know how this works for you.

Regards,
Dimitar
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Phil
Top achievements
Rank 1
answered on 08 Jun 2017, 09:37 PM

Thanks for the info. It helps knowing that async threads are involved.

For our purposes this solution doesn't fit since a number of other tasks are performed between the two loads and these shouldn't wait for the first PDF to load before continuing. Changing this solution to a Task based or event based solution with awaits or queues unfortunately over complicates things as well and it's much better for us to rather completely ignore the placeholder altogether or simply overlay a static placeholder within a panel or separate placeholder viewer - maintainability vs complexity in this case.

Can I please request an additional override either to UnloadDocument or LoadDocument or a separate method for canceling a load? So if this additional parameter is passed or this method is called it will cancel the async load. Understandably if the async load is passed the point of no return there's not much choice.

Alternatively can I please request that when subsequent LoadDocument calls are made that if the previous load can be stopped it will be, if it cannot then the subsequent load will wait for the first load to complete and then replace it?

These solutions would work best for us and I can think of a lot of scenarios where people would be navigating through lists of documents and some previews may still be loading when a different document is already selected.

0
Dimitar
Telerik team
answered on 09 Jun 2017, 12:02 PM
Hi Phil,

There is no need to wait for the document loading before executing your tasks. The LoadDocument method would not stop the main thread. So you can put all your tasks after this and wait only before loading the second time. This way your tasks and the document loading will be executed simultaneously and you will wait only if the document loading is slower. Have you tried this approach?

In addition, I have logged your request in our Feedback Portal. You can track its progress, subscribe for status changes and add your comment to it here. I have also updated your Telerik Points.

Should you have any other questions do not hesitate to ask.

Regards,
Dimitar
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Phil
Top achievements
Rank 1
answered on 10 Jun 2017, 04:51 AM

No I haven't implemented that approach. I know it will work but the behaviour doesn't suit our scenario and it requires additional event handling and fiddling which will complicate things.

We have two disparate methods with no knowledge of each other, one to reset to the placeholder and one to display the chosen PDF and they can both be called at any time. I don't want to have to add additional logic to track which PDF is actually meant to currently be displayed or to fiddle with existing code which works 100% as is with other another viewer.

It is much better for us to rather skip those changes and keep things unified across the board. Code maintainability is critical to us and unnecessary event chains are against our policy.

Thanks very much for your assistance though!
0
Dimitar
Telerik team
answered on 12 Jun 2017, 06:13 AM
Hello Phil,

I can suggest another solution which does not require using events. Here is the code:
var bgworker = radPdfViewer1.PdfViewerElement.GetType().GetField("documentLoader", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(radPdfViewer1.PdfViewerElement) as BackgroundWorker;
 
while (bgworker.IsBusy)
{
    Thread.Sleep(300);
    Application.DoEvents();
 
}

I hope this will be useful. 

Regards,
Dimitar
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Phil
Top achievements
Rank 1
answered on 13 Jun 2017, 03:57 AM

Thanks for that. It is quite an exotic way of doing things ;} I learned something new too!

It is helpful. Instead of allowing the worker to continue we would basically cancel the work and carry on.

We've actually finalised our changes around this so we won't be using this now but will keep it mind for future usage.

0
Dimitar
Telerik team
answered on 13 Jun 2017, 08:01 AM
Hello Phil,

I am glad that you managed to find a solution for this case. Do not hesitate to contact us if you have other questions.
 
Regards,
Dimitar
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
PdfViewer and PdfViewerNavigator
Asked by
Phil
Top achievements
Rank 1
Answers by
Dimitar
Telerik team
Phil
Top achievements
Rank 1
Share this question
or