简体   繁体   English

下载文件时我无法更新进度栏

[英]I cant update progress bar while downloading a file

I am trying to make a simple download manager.and it works.The problem is that if i add a progressbar to inform the user I am getting this exception 我正在尝试制作一个简单的下载管理器,并且它可以工作。问题是,如果我添加一个进度条来通知用户,我将收到此异常

This stream does not support seek operations 此流不支持搜索操作

 while ((readed = ReadFrom.Read(read, 0, read.Length)) > 0)
            {

                strLocal.Write(read, 0, readed);
                **UpdateProgress(ReadFrom.Length, strLocal.Length);// throws exception**
            }

this the all code 这是所有代码

  private void button1_Click(object sender, EventArgs e)
        {
            req = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
            res = (HttpWebResponse)req.GetResponse();
            Int64 contentlength = res.ContentLength;
            WebClient wc = new WebClient();
            Stream ReadFrom= wc.OpenRead(new Uri(url));

            strLocal = new FileStream(@"E:\\xxx.tar.gz", FileMode.Create, FileAccess.Write, FileShare.None);
            byte[]read=new byte[1024];

            int readed = 0;
            while ((readed = ReadFrom.Read(read, 0, read.Length)) > 0)
            {

                strLocal.Write(read, 0, readed);
                UpdateProgress(ReadFrom.Length, strLocal.Length);
            }

            strLocal.Close();
            ReadFrom.Close();

        }

        private void UpdateProgress(long Filesize, long readedBytes)
        {
          //  progressBar1.Maximum = 100;
         int downloaded =Convert.ToInt32((readedBytes * 100) / Filesize);
         progressBar1.Value = downloaded;
        }

What is wrong here? 怎么了

@Edit @编辑

        HttpWebRequest req;
        HttpWebResponse res;
        Stream strLocal;
        Stream ResponseStr;
        byte[] bytes = null;
        Thread thr;
        delegate void UpdateCallBack(long l1, long l2);
        public Form1()
        {
            InitializeComponent();
        }
        string url="https://www.unrealircd.org/downloads/Unreal3.2.10.3.tar.gz";
        ////string url2 = "http://www.microsoft.com/en-us/download/confirmation.aspx?id=34794&6B49FDFB-8E5B-4B07-BC31-15695C5A2143=1";
        string filename = @"C:\\Unreal3.2.10.3.tar.gz";
        private void Form1_Load(object sender, EventArgs e)
        {

        }



        private void button1_Click(object sender, EventArgs e)
        {
            thr = new Thread(download);
            thr.Start();

        }

private void download()
{
            req = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
            res = (HttpWebResponse)req.GetResponse();

            Int64 contentlength = res.ContentLength;

            ResponseStr = res.GetResponseStream();

            strLocal = new FileStream(@"E:\\xxx.tar.gz", FileMode.Create, FileAccess.Write, FileShare.None);
            byte[]read=new byte[1024];

            int readed = 0;
            while ((readed = ResponseStr.Read(read, 0, read.Length)) > 0)
            {

                strLocal.Write(read, 0, readed);
                this.Invoke(new UpdateCallBack(this.UpdateProgress), new object[] {ResponseStr.Length,strLocal.Length });


            }

            strLocal.Close();
            ResponseStr.Close();
}

        private void UpdateProgress(long Filesize, long readedBytes)
        {

         int updated =Convert.ToInt32((readedBytes * 100) / Filesize);
         progressBar1.Value = updated;
        }

@edit2 @ EDIT2

private void download()
{
            req = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
            res = (HttpWebResponse)req.GetResponse();

            Int64 contentlength = res.ContentLength;

            ResponseStr = res.GetResponseStream();


            strLocal = new FileStream(@"E:\\xxx.tar.gz", FileMode.Create, FileAccess.Write, FileShare.None);


            byte[]read=new byte[1024];

            int readed = 0;
            while ((readed = ResponseStr.Read(read, 0, read.Length)) > 0)
            {

                strLocal.Write(read, 0, readed);
                backgroundWorker1.RunWorkerAsync();
              //  this.Invoke(new UpdateCallBack(this.UpdateProgress), new object[] {ResponseStr.Length,strLocal.Length });


            }

            strLocal.Close();
            ResponseStr.Close();
}

        private void UpdateProgress(long Filesize, long readedBytes)
        {

         int updated =Convert.ToInt32((readedBytes * 100) / Filesize);
         progressBar1.Value = updated;
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            UpdateProgress(ResponseStr.Length, strLocal.Length);
        }

All of your operations are happening on the same thread. 您的所有操作都在同一线程上进行。 While you are doing the download, the application halts the UI from being updated. 在进行下载时,该应用程序将停止UI更新。 I typically use a BackgroundWorker to update progress bars for situations like this. 对于这种情况,我通常使用BackgroundWorker更新进度条。

Here's an MSDN resource on background workers. 这是有关后台工作者的MSDN资源。

Based on your edit, here is some code for you: 根据您的编辑,以下是适合您的代码:

// At the class level, put this:
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true; // This means we want to send updates from the background worker.

// The DoWork method handles your time consuming task, which in this case is your download method. So you can try this:
private void Download()
{
    bw.RunWorkerAsync();
}

// This should be called as a result:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    // The worker who's progress will be updated.
    BackgroundWorker worker = sender as BackgroundWorker;

    req = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
    res = (HttpWebResponse)req.GetResponse();

    Int64 contentLength = res.ContentLength;

    ResponseStr = res.GetResponseStream();

    strLocal = new FileStream(@"E:\xxx.tar.gz", FileMode.Create, FileAccess.Write, FileShare.None);

    byte[] read = new byte[1024];

    int readed = 0;
    while((readed = ResponseStr.Read(read, 0, read.Length)) > 0)
    {
        strLocal.Write(read, 0, readed);
        // Update the worker (this uses the number you calculated)
        worker.ReportProgress(Convert.ToInt32((ResponseStr.Length * 100) / strLocal.Length));

        strLocal.Close();
        ResponseStr.Close();
    }
}

// This is called via worker.ReportProgress
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

You need to define the background worker in your class, and allow it to accept progress updates. 您需要在您的课程中定义后台工作程序,并允许其接受进度更新。

Then, wherever this method that requires the background worker is, you need to call RunWorkerAsync . 然后,无论此方法需要后台工作人员在哪里,都需要调用RunWorkerAsync You can do this inside the download method, or replace the spot where you call download. 您可以在下载方法中执行此操作,也可以替换调用下载的位置。

In your do work class, you do all the stuff you normally would, but at the situation where you want to update progress, you can call ReportProgress with the necessary value. 在do work类中,您可以执行通常的所有工作,但是在要更新进度的情况下,可以使用必要的值调用ReportProgress

If you look at the link above, there are other methods that can be implemented - if you are concerned about cancelling the background worker or if there is an error or anything else. 如果您查看上面的链接,还有其他可以实现的方法-如果您担心取消后台工作程序或出现错误或其他任何情况。

EDIT 编辑

If you are still receiving an error, I just realized that it may be the fact that you are trying to pull the length from a Stream object. 如果您仍然收到错误,我只是意识到您可能正在尝试从Stream对象提取长度。 Take a look at this question if the error persists. 如果错误仍然存​​在,请看这个问题

As said above it has to do with the threads. 如上所述,它与线程有关。 So you need to seperate the actions over multiple threads to be able to update your UI. 因此,您需要将操作分开在多个线程上才能更新UI。 You can also use async and await to solve this issue. 您还可以使用异步并等待以解决此问题。 Below is a nice article about it, the article is about doing some action and updating the UI. 以下是一篇不错的文章,该文章是关于执行一些操作和更新UI的。

http://www.i-programmer.info/programming/c/1514-async-await-and-the-ui-problem.html http://www.i-programmer.info/programming/c/1514-async-await-and-the-ui-problem.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM