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

Reply via email to