【问题标题】:Stop a Stream of Data Before End Of File在文件结束之前停止数据流
【发布时间】:2011-08-27 20:48:09
【问题描述】:

在我的 Silverlight 应用程序中,我需要下载大文件。我目前通过在托管 Silverlight 应用程序的同一服务器上调用 ASPX 页面来从字节数组中流式传输这些数据。 ASPX Page_Load() 方法如下所示:

protected void Page_Load(object sender, EventArgs e)
{
  // we are sending binary data, not HTML/CSS, so clear the page headers
  Response.Clear();
  Response.ContentType = "Application/xod";

  string filePath = Request["file"];  // passed in from Silverlight app

  //  ...

  using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
  {
    // send data 30 KB at a time
    Byte[] t = new Byte[30 * 1024];

    int bytesRead = 0;
    bytesRead = fs.Read(t, 0, t.Length);
    Response.BufferOutput = false;

    int totalBytesSent = 0;

    Debug.WriteLine("Commence streaming...");
    while (bytesRead > 0)
    {
      // write bytes to the response stream
      Response.BinaryWrite(t);

      // write to output how many bytes have been sent
      totalBytesSent += bytesRead;
      Debug.WriteLine("Server sent total " + totalBytesSent + " bytes.");

      // read next bytes
      bytesRead = fs.Read(t, 0, t.Length);
    }
  }

  Debug.WriteLine("Done.");

  // ensure all bytes have been sent and stop execution
  Response.End();
}

从 Silverlight 应用程序,我只是将 uri 交给读取字节数组的对象:

Uri uri = new Uri("https://localhost:44300/TestDir/StreamDoc.aspx?file=" + path);

我的问题是......如果用户取消,我该如何停止这个流?就像现在一样,如果用户选择另一个文件来下载,新的流将开始,前一个流将继续流,直到完成。

一旦流开始,我找不到中止流的方法。

非常感谢任何帮助。

-斯科特

【问题讨论】:

  • 除此之外,您总是假设 Read 调用会填满缓冲区,因为您随后会写出整个缓冲区而不是刚刚读取的字节。
  • 不确定我是否遵循,但缓冲区中永远不会超过 30k,是的,然后我将整个 30k(或更少)发送回响应通道。
  • 但其中的有用数据可能少于 30K。您应该只在每次迭代中写入 bytesRead 字节,而不是整个 30K。
  • 啊,我明白你现在在说什么了。好眼光 - 我会努力解决这个问题。实际上,我对它的工作感到有点震惊,因为读取的字节和每次迭代的 30k 限制之间可能存在垃圾。我猜我很“幸运”,并且在我的测试中每次都读取了完整的 30k。
  • 从本地磁盘读取通常会填满缓冲区。但是你的最后一次迭代几乎总是错误的——你可能有很多文件都有尾随垃圾,事实上。当然,在某些文件格式中并不重要。

标签: asp.net silverlight stream


【解决方案1】:

如果您确定只有 30K 的数据,您可以考虑使用 File.ReadAllBytes 对其进行简化。

【讨论】:

    【解决方案2】:

    如果您使用HttpWebRequest.Abort 中止客户端上的请求(如this 答案中),则应在服务器上引发ThreadAbortException 以响应TCP ​​连接的结束,这将停止该线程写出数据。

    【讨论】:

      【解决方案3】:

      我只是将 uri 交给读取字节数组的对象

      我暂时假设您只是使用WebClientWebClient 有一个 CancelAsync 方法。 OpenReadCompleted 的 eventargs 有一个 Cancelled 可以测试的属性。

      当客户端中止连接时,服务器将不再发送任何字节,但服务器代码将继续运行,这是 IIS 的内部结构,它将简单地丢弃它收到的缓冲区,因为它不再有任何地方可以发送它们。

      在服务器上,您可以使用HttpResponse 对象的IsClientConnected 属性来确定是否中止泵循环。

      顺便说一句,您真的应该考虑将此代码移至 .ashx,.aspx 带有很多您不需要的包袱。

      【讨论】:

        猜你喜欢
        • 2021-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-30
        • 1970-01-01
        • 2011-07-06
        相关资源
        最近更新 更多