2012-04-19 106 views
0

您好在主要形式中有一個名爲Dlist的ListView,我有一個後臺工作人員下載文件,在後臺工作人員如何編輯主窗體列表視圖中的子進程「進度」?從背景工作者訪問ListView

我的代碼:

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();)它是更新列表視圖,但我不斷獲得交叉線程。

回答

1

因爲背景工作者確實是一個不同的線程,與UI線程分離,您需要檢查是否需要調用該用戶控件。 下面是一個有點源代碼我用ListView1的是你的DLIST的..

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); 
     } 
    } 
1

,而不必擔心不必使用代表和來自Do_Work方法調用它,我將設置BackgroundWorker.WorkerReportsProgress爲true,訂閱BackgroundWorker.ProgressChanged事件。處理該事件將發生在UI線程上,您可以通過從參數中提取報告並從那裏更新ListView來使用報告的進度(如從Do_Work方法調用的那樣)。