Welcome Guest Search | Active Topics | Sign In | Register

Progress Bar Not Working with Zip Utility Options
goodfella
Posted: Monday, June 22, 2009 7:07:57 PM
Rank: Newbie
Groups: Member

Joined: 6/22/2009
Posts: 3
Hello,

I am trying to use your Progress Bar component to show progress of a zip file being compressed (in code). Once complete (and the progress bar reaches 100%), the file would then be ready to the user through the browser's dialog box.

However, whenever I include the code that actually creates the zip file, the progress bar no longer works. I've narrowed it down to the following snippet that is causing the problem:

Code: C#
using (FileStream fileStream = File.OpenRead(filesToZip[i]))
{

  byte[] buffer = new byte[fileStream.Length];
  fileStream.Read(buffer, 0, buffer.Length);

  entry.Size = fileStream.Length;
  fileStream.Close();

  crc.Reset();
  crc.Update(buffer);
  entry.Crc = crc.Value;

   //add the zip entry to the stream.
   zipStream.PutNextEntry(entry);
   zipStream.Write(buffer, 0, buffer.Length);
}


Even when I remove everything inside the using brackets, it still breaks. Is there something inherently incompatible with this and the progress bar?

Thank you!
eo_support
Posted: Monday, June 22, 2009 7:51:59 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

The ProgressBar should not have any issue with zip file. You may have misunderstood how ProgressBar works. Please see this post for more details:

http://www.essentialobjects.com/forum/postst3324_Progress-Bar-Help.aspx

Thanks
goodfella
Posted: Monday, June 22, 2009 8:10:16 PM
Rank: Newbie
Groups: Member

Joined: 6/22/2009
Posts: 3
Hello,

Thanks for your reply.

We're not using a Fileupload control (as we are not uploading files to the server to be zipped, but rather taking existing files on the server, zipping them into a memory stream, and then pushing the file to the user). They are similar I suppose, so is the issue the same and therefore, I need to find a way to return progress from the Zip control?

I was just trying to follow what the commented code mentioned:

//Here we call Thread.Sleep just for demonstration
//purpose. You should replace this with code that
//performs your long running task.

So in my case, this wouldn't work, right?

Thanks again for your help and all of your controls seem rather nice. Look forward to using them.


eo_support
Posted: Monday, June 22, 2009 8:30:18 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

Yes. You are exactly right: you need to find a way to return progress info from the zip routine. The ProgressBar does not know how long your zip code will run so it won't be able to figure out the current progress on its own. As such you always need to report the progress to the progress bar.

As to the sample code, you would regard the whole RunTask handler as your long running task routine. For example, if your long running task is copying 100 files, you would loop 100 times like the sample code does, but replacing Thread.Sleep with code to copy one file. Here "copying 100 files" is your task, not "copying a single file". Likewise, If you whole task is just copying one file, you might want to get the file length first, then run a loop to copy chunk by chunk. Here you would replace Thread.Sleep with code to copy a single chunk. All these goes down to one thing: you need to keep reporting the progress to the progress bar.

Hope this helps.

Thanks!
goodfella
Posted: Tuesday, June 23, 2009 3:42:05 PM
Rank: Newbie
Groups: Member

Joined: 6/22/2009
Posts: 3
Thanks again for your help. Makes crystal clear sense (so I think).

I implemented the changes and have a functioning progress bar. However, once the progress bar reaches 100, the intent is to then continue with one more bit of code to push to the zipped file to the user. However, once the progress bar reaches 100, none of the code seems to work (I tried a simple Response.Write and Response.Redirect).

Here is the code I have thus far, for the entire process. Thanks again for your time:

Code: C#
e.UpdateProgress(0);
        this.memoryStream = new MemoryStream();
        ZipOutputStream zip = null;
        ArrayList filenames = new ArrayList();

        foreach (ListItem li in cblDrugs.Items)
        {
            if (li.Selected == true)
            {
                // Add to zip file
                filenames.Add(CommonLib.GlobalData.PDFDirectory + li.Value + "_DataSheet.pdf");
            }
        }

        string[] filesToZip = new string[filenames.Count];
        int z = 0;
        foreach (string sFilename in filenames)
        {
            filesToZip[z] = sFilename;
            z++;
        }

        ZipOutputStream zipStream = new ZipOutputStream(this.memoryStream);
        zipStream.SetLevel(9); // 0 - store only to 9 - means best compression

        Crc32 crc = new Crc32();

        int x = 0;
        int denom = (100 / filesToZip.Length);
        for (int i = 0; i < filesToZip.Length; i++)
        {
            // Must use a relative path here so that files show up in the Windows Zip File Viewer
            // .. hence the use of Path.GetFileName(...)
            string fileName = Path.GetFileName(filesToZip[i]);

            //each zipentry is one file in the zip archive
            ZipEntry entry = new ZipEntry(fileName);
            entry.DateTime = DateTime.Now;

            // Read in the files one by one.
            using (FileStream fileStream = File.OpenRead(filesToZip[i]))
            {
                byte[] buffer = new byte[fileStream.Length];
                fileStream.Read(buffer, 0, buffer.Length);

                entry.Size = fileStream.Length;
                fileStream.Close();

                crc.Reset();
                crc.Update(buffer);
                entry.Crc = crc.Value;

                //add the zip entry to the stream.
                zipStream.PutNextEntry(entry);
                zipStream.Write(buffer, 0, buffer.Length);
            }

            System.Threading.Thread.Sleep(300);
            x += denom;
            e.UpdateProgress(x);
            
        }

        zipStream.Finish();
        e.UpdateProgress(100, "Documents ready for download!");
            
        Response.Clear();
        Response.AddHeader("Content-Type", "binary/octet-stream");
        Response.AddHeader("Content-Length", zip.Length.ToString());

        //the filename might be dynamic as well.
        Response.AddHeader("Content-Disposition",
             "attachment; filename=DataSheets.zip; size="
             + zipStream.Length.ToString());
        Response.Flush();

        //one line of code to send back the stream.  Sweet!
        Response.BinaryWrite(this.memoryStream.ToArray());

        Response.Flush();
        Response.End();

        this.memoryStream.Close();
        this.memoryStream.Dispose();
eo_support
Posted: Tuesday, June 23, 2009 3:51:42 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

You can not update anything other than the ProgressBar inside RunTask handler. If you wish to perform anything else, exit RunTask and some how (more below) triggers another post back then do whatever you need inside that separate post back.

You will need to detect whether the progress bar is done from your ClientSideOnValueChanged handler, and once it is done, trigger a post back from JavaScript. Usually you would do so by calling __doPostBack. If you are not familiar with this, you can put a LinkButton inside your page, run the page and then view page source to see what code it calls when the link is clicked. You can copy that code to trigger the LinkButton’s Click event (make sure the LinkButton is still in the page, you may need to put it inside a hidden DIV so that it is not visible).

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.