在我的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);
我的问题是……如果用户取消,我如何停止这个流?就像现在一样,如果用户选择另一个文件来下载,新的流将开始,前一个流将继续流,直到它完成。
我找不到一种方法来中止流,一旦它开始。
任何帮助都非常感谢。
斯科特
如果您确定只有30K的数据,您可以考虑使用File.ReadAllBytes.
如果您在客户端上使用HttpWebRequest.Abort
中止请求(就像在这个答案中一样),那么服务器上应该提出一个ThreadAbortException
以响应TCP连接的结束,这将停止该线程写数据。
我只是把uri交给对象来读取字节数组
我假设您现在只是使用WebClient
。WebClient
有一个CancelAsync
方法。OpenReadCompleted
的eventargs有一个Cancelled
的属性可以测试。
当客户端终止连接时,服务器将不再发送任何字节,但服务器代码将继续运行,这是IIS的内部,它将丢弃它接收到的缓冲区,因为它不再有任何地方可以发送它们。
在服务器上,你可以使用HttpResponse
对象的IsClientConnected
属性来决定是否中止泵循环。
顺便说一句,你真的应该考虑把这段代码移到。aspx上,.aspx承载了很多你不需要的包袱。