0

こんにちは、Dlistと呼ばれるメインフォームにListViewがあります。ファイルをダウンロードするバックグラウンドワーカーがあります。バックグラウンドワーカーで、メインフォームのリストビューのサブアイテム「Progress」を編集するにはどうすればよいですか?

私のコード:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (obj, e) => WorkerDoWork(link, savepath,Dlist);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(progress_complete);
worker.ProgressChanged += new ProgressChangedEventHandler(progress_changed);
worker.RunWorkerAsync();


rivate void WorkerDoWork(string link, string savepath, ListView Dlist)
    {
        // Start Download
        Uri url = new Uri(link);
        System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
        System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
        response.Close();
        Int64 iSize = response.ContentLength;
        Int64 iRunningByteTotal = 0;
        using (System.Net.WebClient client = new System.Net.WebClient())
        {
            using (System.IO.Stream streamRemote = client.OpenRead(new Uri(link)))
            {
                using (Stream streamLocal = new FileStream(savepath, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    int iByteSize = 0;
                    byte[] byteBuffer = new byte[256];
                    while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
                    {
                        streamLocal.Write(byteBuffer, 0, iByteSize);
                        iRunningByteTotal += iByteSize;
                        double dIndex = (double)(iRunningByteTotal);
                        double dTotal = (double)byteBuffer.Length;
                        double dProgressPercentage = (dIndex / dTotal);
                        int iProgressPercentage = (int)(dProgressPercentage * 100);
                        //Dlist.Items[Dlist.Items.IndexOfKey(fileName)].SubItems[2].Text = iProgressPercentage.ToString();
                    }
                    streamLocal.Close();
                }
                streamRemote.Close();
            }
        }
    }

この行(// Dlist.Items [Dlist.Items.IndexOfKey(fileName)]。SubItems [2] .Text = iProgressPercentage.ToString();)リストビューを更新しますが、クロススレッドが発生し続けます。

4

3 に答える 3

0

backgroundworkerは実際には別のスレッドであるため、UIスレッドとは別に、そのユーザーコントロールに呼び出しが必要かどうかを確認する必要があります。以下は私があなたのDlistであるlistView1を使用するソースコードのビットです。

    delegate void SetListViewItemCallBack(ListViewItem Item);
    private void AddListViewItem(ListViewItem Item)
    {
        if (this.listView1.InvokeRequired)
        {
            SetListViewItemCallBack d = new SetListViewItemCallBack(AddListViewItem);
            this.Invoke(d, new object[] { Item });
        }
        else
        {
            this.listView1.Items.Add(Item);
        }
    }
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        DataSet dsInfo = // whatever you want..
        for (int i = 0; i < dsInfo.Tables[0].Rows.Count; i++)
        {
            ListViewItem li = new ListViewItem();
            li.Text = dsInfo.Tables[0].Rows[i]["AXT_Tag"].ToString();
            li.Tag = dsInfo.Tables[0].Rows[i]["AXT_ID"].ToString();
            AddListViewItem(li);
        }
    }
于 2012-04-19T11:35:59.237 に答える
0

BackgroundWorker.ReportProgressメソッドを使用しないのはなぜですか(例のセクションを参照)。

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

于 2012-04-19T11:40:27.050 に答える
0

デリゲートを使用してDo_Workメソッドから呼び出す必要があることを心配するのではなく、BackgroundWorker.WorkerReportsProgressをtrueに設定し、 BackgroundWorker.ProgressChangedイベントをサブスクライブします。そのイベントの処理はUIスレッドで発生し、引数からイベントを抽出してそこからListViewを更新することにより、(Do_Workメソッドから呼び出された)報告された進行状況を使用できます。

于 2012-04-19T11:42:07.563 に答える