C# MemoryStream vs.FileStream:文档查看器成功地从FileStream呈现文档,但不是MemoryStream?

C# MemoryStream vs.FileStream:文档查看器成功地从FileStream呈现文档,但不是MemoryStream?,c#,silverlight,pdf,stream,streaming,C#,Silverlight,Pdf,Stream,Streaming,我正在silverlight应用程序中使用C1的PDF查看器控件,并且正在测试最大PDF大小限制。 我有一个35MB的PDF文件 当我通过OpenFileDialog加载PDF查看器时,只需将文件流发送给它,它就会呈现良好的效果。全部900页 但是,当我试图通过从字节[]创建的MemoryStream加载PDF查看器时,它不会呈现任何内容。它不会出错,只是呈现为空白 这是完全相同的文件。而且MemoryStream过程可以成功地处理更小的PDF文档。然而,FileStream方法可以处理较大的文

我正在silverlight应用程序中使用C1的PDF查看器控件,并且正在测试最大PDF大小限制。 我有一个35MB的PDF文件

当我通过OpenFileDialog加载PDF查看器时,只需将文件流发送给它,它就会呈现良好的效果。全部900页

但是,当我试图通过从字节[]创建的MemoryStream加载PDF查看器时,它不会呈现任何内容。它不会出错,只是呈现为空白

这是完全相同的文件。而且MemoryStream过程可以成功地处理更小的PDF文档。然而,FileStream方法可以处理较大的文档,所以我知道这不是PDF查看器的限制,对吗

文件流方法:

        OpenFileDialog ofd = new OpenFileDialog();
        bool? res = ofd.ShowDialog();
        if (res == true)
        {
            FileStream stream = ofd.File.OpenRead();
            docViewer.LoadDocument(stream);
        }
       imageBytes = File.ReadAllBytes(path);
       MemoryStream stream = new MemoryStream();
       stream.Write(imageBytes, 0, imageBytes.Length);
       stream.Seek(0, SeekOrigin.Begin);
       docViewer.LoadDocument(stream);
记忆流方法:

        OpenFileDialog ofd = new OpenFileDialog();
        bool? res = ofd.ShowDialog();
        if (res == true)
        {
            FileStream stream = ofd.File.OpenRead();
            docViewer.LoadDocument(stream);
        }
       imageBytes = File.ReadAllBytes(path);
       MemoryStream stream = new MemoryStream();
       stream.Write(imageBytes, 0, imageBytes.Length);
       stream.Seek(0, SeekOrigin.Begin);
       docViewer.LoadDocument(stream);
这给了我同样的结果。空白查看器:

using (MemoryStream stream = new MemoryStream(imageBytes))
{
      docViewer.LoadDocument(stream);
}
又一次…因失败而沮丧。 我重构了调用以使用“OpenReadAsync”,然后修改了API调用(我们使用MVC作为伪API)以返回流,它仍然呈现为空。 结果内部流的长度也是正确的

客户电话:

        string url = App.Server + "Document/RetrievePDFTest";
        try
        {
            WebClient wc = new WebClient();
            wc.OpenReadCompleted += new OpenReadCompletedEventHandler(delegate(object sender, OpenReadCompletedEventArgs e)
            {
                if (e.Result != null)
                {
                    docViewer.LoadDocument(e.Result);
                }
            });
            wc.OpenReadAsync(new Uri(url));
        }
        catch (Exception ex)
        {
            //TODO - handle exception
        }
服务器API:

    public ActionResult RetrievePDFTest()
    {
        return File(System.IO.File.ReadAllBytes("D://temp//repositories//test35mb.PDF"), "application/pdf");
    }
更新!!!! 我相信我已经发现了可能存在的问题

在我的silverlight应用程序中,我实际上是在一个新窗口中弹出这个文档查看器,然后我向这个新窗口发送从服务器检索PDF图像的信息。本质上,我通过传递的密钥告诉它要检索哪个文档:

this.windowManager.NavigateToPageInNewWindow("/Views/pdfViewerUserControl.xaml");
                LocalMessageSender s = new LocalMessageSender("receiver", LocalMessageSender.Global);
                s.SendAsync(doc.Barcode);
现在,在我的pdfViewerUserControl.xaml中,我在它的构造函数中创建并注册消息的侦听器:

public pdfViewerUserControl()
    {
        LocalMessageReceiver messageReceiver = new LocalMessageReceiver("receiver", ReceiverNameScope.Global, LocalMessageReceiver.AnyDomain);
        messageReceiver.MessageReceived += messageReceiver_MessageReceived;
        try
        {
            messageReceiver.Listen();
        }
        catch (Exception ex)
        {

        }

        // Required to initialize variables
        InitializeComponent();
    }
在“messageReceiver_MessageReceived”事件处理程序中,我在这里进行服务器调用以检索图像并加载查看器。即使服务器返回图像,此过程也会产生一个空白的PDF查看器。(即使是大型pdf)

现在,作为一个测试工具,我在页面上也有一个测试按钮,这个按钮会触发代码中的一个事件,该事件会进行完全相同的服务器调用,并以完全相同的方式加载结果,但这是有效的!!!35MB的大PDF在浏览器中成功呈现


这使我相信在使用LocalMessageSender/LocalMessageReceiver对象时会出现断开连接的情况。

一个可能的原因可能是必须在最后处理内存流对象

using (MemoryStream ms = new MemoryStream())
{
    // Do something with ms..
}
或者在使用内存流对象结束时这样说

stream.Dispose();
stream.Close();

考虑到这些注释,我怀疑问题在于您将其作为字符串下载,然后将其转换为字节。将字节数组中的数据与文件中的数据进行比较(例如,采用MD5哈希)


要下载二进制数据,您应该改为使用
DownloadData

问题似乎与查看器或PDF文件无关。这与无法在我所处的上下文中操作UI有关

我正在使用HtmlPage.PopupWindow()弹出一个新窗口,指定另一个usercontrol(我的pdf XAML用户控件,其中包含pdfviewer)作为URI

为了向新窗口传递要检索/查看的文档的键,我在新窗口的用户控件上注册了一个侦听器。 然后我给那个听众发钥匙

在侦听器的MessageReceived事件中,我调用获取字节数组并填充查看器

这似乎不是在更新UI。相反,我放弃了侦听器/发送器模式,只是将键固定到“HtmlPage.PopupWindow()”的URI末尾。 然后在新用户控件页面的构造器中,我从URI和“bob's your uncle”推断出密钥,它起作用了

我仍然不确定我是否在另一个线程上,或者侦听器的“on message received”事件发生了什么。
我在侦听器中遇到了断点,doc viewer的“LoadDocument()”方法没有出错或引发异常,UI只是没有呈现更新。

您可以将填充了
imageBytes
的代码包括在内吗?您在哪里填充imageBytes?您检查了该数组吗?它是否包含编码数据(如文件)或标头+像素缓冲区?如果打开文件流并将其复制到内存流会发生什么?为什么不调用
newmemorystream(imageBytes)
出于兴趣?@MVelasquez:当然,你不应该对二进制数据使用DownloadString。WebClient对象没有“DownloadData”方法。在任何情况下,此方法都能成功地用于我测试过的其他文档。@MVelasquez:使用
OpenReadAsync
方法和
OpenReadCompleted
事件事件args的
Result
属性就是您要查找的流。我来试一试。谢谢你们对我的耐心。将返回报告。@MVelasquez:是时候找出fiddler并检查服务器实际发送的内容了。尝试将响应实体体保存为PDF,它是否在标准阅读器中打开?实际上,我进一步缩小了范围,发现它不是PDF本身,而是我检索它的方法。似乎在使用LocalMessageReceiver事件检索它并将其加载到docviewer时,它失败了。但当我使用一个简单的按钮点击事件处理程序检索并加载它时,它成功了。有人知道为什么LocalMessageReceiver接收到的事件会产生不同的结果吗?