Threaded Download ZipFile.Save(Response.OutputStream)

Aug 29, 2013 at 6:03 PM
Hello,

I am having trouble implementing a threaded version of the Response.OutputStream example.

All runs well as non-threaded, however, when I try to call the same method(downloadArchiveThread) via ThreadPool.QueueUserWorkItem or spin up my our thread(StartBackgroundThread), the resulting zip file is 'invalid'. My code listed below.

My goal is to free up the browser on larger zip file downloads as the non-threaded implementation ties up the browser user interface until the download is complete.

Thank you.


public void downloadArchive(Object sender, EventArgs e)
{
try
{
    string filename = txtName.Text + ".zip";
    string dirPath = myDirPath;

    downloadArchiveThread(dirPath, txtName.Text, folderName);  // works perfectly, except ties up browser
    //ThreadPool.QueueUserWorkItem(o => downloadArchiveThread(dirPath, txtName.Text, folderName));  // 'invalid' zip file downloaded
    //StartBackgroundThread(delegate { downloadArchiveThread(dirPath, txtName.Text, folderName); }); // 'invalid' zip file downloaded
}
catch (Exception ex) { throw (ex); }
}

public void downloadArchiveThread( string dirPath, string baseFileName, string folderName)
{
Response.Clear();
Response.BufferOutput = false;  // for large files
Response.ContentType = "application/zip";
string fileName = baseFileName + ".zip";
Response.AddHeader("content-disposition", "filename=" + fileName);

lock (objLock){

    try
    {
        using (ZipFile zip = new ZipFile())
        {
            zip.AddDirectory(dirPath, folderName);
            zip.Save(Response.OutputStream);
        }
    }
    catch (Exception ex) { Response.Write("error: " + ex.Message); Response.Close(); }

    if (!Response.IsClientConnected)
    {
        Response.Close();
    }

}
}


public static void StartBackgroundThread(ThreadStart threadStart)
{
if (threadStart != null)
{
    Thread thread = new Thread(threadStart);
    thread.IsBackground = true;
    thread.Start();
}
}