在文件结束前停止数据流

时间:2011-08-27 20:48:09

标签: asp.net silverlight stream

在我的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);

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

我无法找到一种方法在流启动后中止流。

任何帮助都非常适合。

-Scott

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

  

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

我现在假设您只是使用WebClientWebClientCancelAsync方法。 OpenReadCompleted的事件标签具有您可以测试的Cancelled属性。

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

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

顺便说一下,你真的应该考虑将这个代码移到.ashx,.aspx带有很多你不需要的包袱。