2

現在、アプリケーションに並列ダウンロードを追加しようとしていますが、DownloadProgressChangedEvent を処理して複数の進行状況バーに進行状況を表示する方法がわかりません。

ユーザーがダウンロードできるファイルごとに事前定義された行を持つデータグリッドビューを使用しており、各行にはプログレスバーのあるセルがあります。

現在の問題は、各プログレスバーを個別に更新する方法がわからないことです。現在、選択されているすべてのプログレスバーが同じパーセンテージを示しており、ダウンロード 1 とダウンロード 2 の進行状況の間をジャンプしているだけだからです。

使用しているコードは次のとおりです。

ダウンロードを開始するには:

private void download_button_Click(object sender, EventArgs e)
    {
        start = DateTime.Now;
        download_button.Enabled = false;

        Rows = dataGridView1.Rows.Count;
        Checked = 0;

        CheckedCount = 0;

            //count the selected rows
            for (i = 0; i < Rows; i++)
            {
                Checked = Convert.ToInt32(dataGridView1.Rows[i].Cells["checkboxcol"].FormattedValue);

                CheckedCount += Checked;

                richTextBox3.Text = CheckedCount.ToString();
            }


        for (int z = 1; z < CheckedCount; z++)
        {             
            _MultipleWebClients = new WebClient();

            _MultipleWebClients.DownloadFileCompleted += new AsyncCompletedEventHandler(_DownloadFileCompleted);
            _MultipleWebClients.DownloadProgressChanged += new System.Net.DownloadProgressChangedEventHandler(_DownloadProgressChanged);
            _MultipleWebClients.DownloadFileAsync(new Uri(_downloadUrlList[z].ToString()), @"F:\test" + z + ".mp4");     
        }

    }

(2 つ以上のファイルを同時にダウンロードすることもできません。最初の 2 つが完了するまで、3 つ目のダウンロードは開始されません)


DownloadProgressChangedEvent:

    private void _DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
        for (int c = 0; c < CheckedCount; c++)
        {
            dataGridView1.Rows[_downloadRowNrList[c]].Cells[3].Value = e.ProgressPercentage;
        }

        float size = ((e.TotalBytesToReceive / 1024) / 1024);
        label1.Text = size.ToString();

        double dn = (double)e.BytesReceived / 1024.0 / (DateTime.Now - start).TotalSeconds;
        label2.Text = (dn.ToString("n") + " KB/s) " + e.ProgressPercentage);        
    }

問題はおそらく、すべてのプログレスバーが同じ DownloadProgressChangedEvent を使用していることですが、必要な数を知らずにこれらのイベントを複数作成する方法がわかりません...

だから私は誰かがこれで私を助けることができることを願っています,

前もって感謝します!

4

2 に答える 2

2

あなたがしたいことは、他のDownloadFileAsync方法を使用することです: http://msdn.microsoft.com/en-us/library/ms144197.aspx

DownloadProgressChangedEventArgs3 番目のパラメーターは、 (プロパティ内にある) の一部として渡される userTokenUserStateです。

そのため、呼び出しを行うときDownloadFileAsyncは、一意のトークン (整数など) を渡して、更新が必要な progressBar に関連付けることができます。

    //(Snip)

    //in download_button_Click, pass the row you are updating to the event.
    for (int z = 1; z < CheckedCount; z++)
    {             
        _MultipleWebClients = new WebClient();

        _MultipleWebClients.DownloadFileCompleted += new AsyncCompletedEventHandler(_DownloadFileCompleted);
        _MultipleWebClients.DownloadProgressChanged += new System.Net.DownloadProgressChangedEventHandler(_DownloadProgressChanged);
        _MultipleWebClients.DownloadFileAsync(new Uri(_downloadUrlList[z].ToString()), @"F:\test" + z + ".mp4", dataGridView1.Rows[z]);     
    }
}

private void _DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    var rowToUpdate = (DataGridViewRow)e.UserState;
    RowToUpdate["ProgressBar"].Value = e.ProgressPercentage;
    RowToUpdate["TextProgress"].Value = e.ProgressPercentage;
    RowToUpdate["BytesToRecive"].Value = ((e.TotalBytesToReceive / 1024) / 1024).ToString();

    double dn = (double)e.BytesReceived / 1024.0 / (DateTime.Now - start).TotalSeconds;
    RowToUpdate["Speed"].Value = (dn.ToString("n") + " KB/s) " + e.ProgressPercentage);
}
于 2012-06-07T01:15:20.247 に答える
0

マルチパートの進行状況には進行状況バーが必要なようです。

public partial class ProgressBarEx : ProgressBar
{
    private readonly Dictionary<Guid, double> _partsProgress =
        new Dictionary<Guid, double>();
    private readonly Dictionary<Guid, double> _partsSizes =
        new Dictionary<Guid, double>();

    private double _value;
    private double _maximum;

    public ProgressBarEx()
    {
        this.InitializeComponent();
    }

    public int Parts
    {
        get { return this._partsSizes.Count; }
    }

    public new int Minimum { get; private set; }

    public new double Maximum
    {
        get { return this._maximum; }
        private set
        {
            this._maximum = value;
            base.Maximum = (int)value;
        }
    }

    public new double Value
    {
        get { return this._value; }
        private set
        {
            this._value = value;
            base.Value = (int)value;
        }
    }

    [Obsolete("Not useable in ProgressBarEx.")]
    public new int Step
    {
        get { return 0; }
    }

    public Guid AddPart(double size)
    {
        if (size <= 0)
        {
            throw new ArgumentException("size");
        }

        var partId = Guid.NewGuid();

        this.Maximum += size;
        this._partsSizes.Add(partId, size);
        this._partsProgress.Add(partId, 0);

        return partId;
    }

    public bool RemovePart(Guid partId)
    {
        double size;
        if (!this._partsSizes.TryGetValue(partId, out size))
        {
            return false;
        }

        this.Maximum -= size;
        this._partsSizes.Remove(partId);

        this.Value -= this._partsProgress[partId];
        this._partsProgress.Remove(partId);

        return true;
    }

    public bool ContainsPart(Guid partId)
    {
        return this._partsSizes.ContainsKey(partId);
    }

    public double GetProgress(Guid partId)
    {
        return this._partsProgress[partId];
    }

    public void SetProgress(Guid partId, double progress)
    {
        if (progress < 0 || this._partsSizes[partId] < progress)
        {
            throw new ArgumentOutOfRangeException("progress");
        }

        this.Value += progress - this._partsProgress[partId];
        this._partsProgress[partId] = progress;
    }

    public void AddProgress(Guid partId, double progress)
    {
        this.SetProgress(partId, progress + this._partsProgress[partId]);
    }

    [Obsolete("Not useable in ProgressBarEx.")]
    public new void PerformStep()
    {
    }
}

使用例:

public Form1()
{
    InitializeComponent();

    var pbe = new ProgressBarEx {Location = new Point(100, 100)};
    this.Controls.Add(pbe);

    for (var i = 0; i < 4; i++)
    {
        var size = i * 10 + 30;

        var partId = pbe.AddPart(size);

        var pb = new ProgressBar
                     {
                         Maximum = size,
                         Location = new Point(100, i * 30 + 130)
                     };

        this.Controls.Add(pb);

        var timer = new Timer {Interval = 1000 + i * 100};

        timer.Tick += (sender, args) =>
                          {
                              pb.Value += 5;
                              pbe.AddProgress(partId, 5);

                              if (pb.Value == pb.Maximum)
                              {
                                  timer.Stop();
                              }
                          };

        timer.Start();
    }
}
于 2012-06-07T02:17:55.573 に答える