O
Omikron
Hi,
I have a problem with downloading large files from the server (approx.
1gb) using http. When around 180mb is downloaded I am getting
timeouts. Files are downloaded in chunks using Response.BinaryWrite
method. I've read that in such situations Asynchronous Http handlers
may come in
rescue. Unfortunetly Msdn doesn't have many examples of their usage.
According to http://msdn.microsoft.com/en-us/library/ms227433.aspx
when it comes to the download in the aspx page I have:
Dim obj_DownloadAsyncHttpHandler As New DownloadFileAsyncHandler()
obj_DownloadAsyncHttpHandler.BeginProcessRequest(Context, Nothing,
obj_AsyncHttpHandlerParameters)
and:
Public Class DownloadFileAsyncHandler
Implements IHttpAsyncHandler
Public Function BeginProcessRequest(ByVal context As
System.Web.HttpContext, ByVal cb As System.AsyncCallback, ByVal
extraData As Object) As System.IAsyncResult Implements
System.Web.IHttpAsyncHandler.BeginProcessRequest
Dim asynch As New DownloadAsynchOperation(cb, context,
extraData)
..........
context.Response.Clear()
context.Response.ClearHeaders()
context.Response.AddHeader("Content-Type", "application/octet-
stream")
context.Response.AddHeader("Content-Length",
intFileSize.ToString())
context.Response.AddHeader("Content-Disposition", "attachment;
filename=" & strFileName)
context.Response.ContentType = "application/octet-stream"
context.Response.Flush()
asynch.StartAsyncWork()
Return asynch
End Function
Class DownloadAsynchOperation
Implements IAsyncResult
Public Sub StartAsyncWork()
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf
StartAsyncTask), Nothing)
End Sub
Private Sub StartAsyncTask(ByVal workItemState As [Object])
................
'writting file chunks here
While intTotalBytesRead < intFileSize
If (Not _context.Response.IsClientConnected) Then
Exit While
End If
Dim async_ChunkDownloadCompleted As New AsyncCallback(AddressOf
ChunkDownloadCompleted)
fileChunk = objFileDownloadHelper.DownloadFileChunk
(filenameWithPath, intTotalBytesRead, size)
If fileChunk IsNot Nothing AndAlso fileChunk.Length > 0 Then
intTotalBytesRead += size
_context.Response.OutputStream.BeginWrite(fileChunk, 0,
fileChunk.Length, async_ChunkDownloadCompleted, Nothing)
End If
End While
......
End Sub
Private Sub ChunkDownloadCompleted(ByVal ar As System.IAsyncResult)
_context.Response.OutputStream.EndWrite(ar)
_context.Response.Flush()
End Sub
I've managed to run this succesfully only once (don't even know how).
Most of the time when it comes to first BeginWrite method call,
standard box to save a file appears but in the meantime I am getting
error "Server cannot flush a completed response." in
ChunkDownloadCompleted or that context.Response.IsClientConnected is
null context and _context are from the aspx page responsible for
downloading. Do you have any ideas why it fails ?
Many thanks
Bartek
I have a problem with downloading large files from the server (approx.
1gb) using http. When around 180mb is downloaded I am getting
timeouts. Files are downloaded in chunks using Response.BinaryWrite
method. I've read that in such situations Asynchronous Http handlers
may come in
rescue. Unfortunetly Msdn doesn't have many examples of their usage.
According to http://msdn.microsoft.com/en-us/library/ms227433.aspx
when it comes to the download in the aspx page I have:
Dim obj_DownloadAsyncHttpHandler As New DownloadFileAsyncHandler()
obj_DownloadAsyncHttpHandler.BeginProcessRequest(Context, Nothing,
obj_AsyncHttpHandlerParameters)
and:
Public Class DownloadFileAsyncHandler
Implements IHttpAsyncHandler
Public Function BeginProcessRequest(ByVal context As
System.Web.HttpContext, ByVal cb As System.AsyncCallback, ByVal
extraData As Object) As System.IAsyncResult Implements
System.Web.IHttpAsyncHandler.BeginProcessRequest
Dim asynch As New DownloadAsynchOperation(cb, context,
extraData)
..........
context.Response.Clear()
context.Response.ClearHeaders()
context.Response.AddHeader("Content-Type", "application/octet-
stream")
context.Response.AddHeader("Content-Length",
intFileSize.ToString())
context.Response.AddHeader("Content-Disposition", "attachment;
filename=" & strFileName)
context.Response.ContentType = "application/octet-stream"
context.Response.Flush()
asynch.StartAsyncWork()
Return asynch
End Function
Class DownloadAsynchOperation
Implements IAsyncResult
Public Sub StartAsyncWork()
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf
StartAsyncTask), Nothing)
End Sub
Private Sub StartAsyncTask(ByVal workItemState As [Object])
................
'writting file chunks here
While intTotalBytesRead < intFileSize
If (Not _context.Response.IsClientConnected) Then
Exit While
End If
Dim async_ChunkDownloadCompleted As New AsyncCallback(AddressOf
ChunkDownloadCompleted)
fileChunk = objFileDownloadHelper.DownloadFileChunk
(filenameWithPath, intTotalBytesRead, size)
If fileChunk IsNot Nothing AndAlso fileChunk.Length > 0 Then
intTotalBytesRead += size
_context.Response.OutputStream.BeginWrite(fileChunk, 0,
fileChunk.Length, async_ChunkDownloadCompleted, Nothing)
End If
End While
......
End Sub
Private Sub ChunkDownloadCompleted(ByVal ar As System.IAsyncResult)
_context.Response.OutputStream.EndWrite(ar)
_context.Response.Flush()
End Sub
I've managed to run this succesfully only once (don't even know how).
Most of the time when it comes to first BeginWrite method call,
standard box to save a file appears but in the meantime I am getting
error "Server cannot flush a completed response." in
ChunkDownloadCompleted or that context.Response.IsClientConnected is
null context and _context are from the aspx page responsible for
downloading. Do you have any ideas why it fails ?
Many thanks
Bartek