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
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

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.
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

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!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

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.
I am glad that you managed to find a solution for this case. Do not hesitate to contact us if you have other questions.
Dimitar
Progress Telerik