2017-09-12 16 views
0

フォームにプログレスバーを使用したいが問題がある。Windowsフォーム埋め込みプログレスバーバックグラウンドワーカー

フォームロード時に、進行状況バーが完了し、リストビューに「接続済み」デバイスのアイコンが表示されます。

ネットワークアダプタのリストで別のインデックスを選択しようとすると、プログレスバーとリストビューはクリアされますが、例外がスローされ、GUIでは何も起こりません。スロー

例外:のSystem.Windows.Forms.dll

の「System.InvalidOperationExceptionが」

私は、これはスレッドの問題であると仮定していますが、私は見当がつかない。

ここにコードがあります。助けやアドバイスは大歓迎です。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Net.NetworkInformation; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class ConnectDialog : Form 
    { 
     BackgroundWorker bkgndWorker = null; 
     Dictionary<string, int> dictionary = new Dictionary<string, int>(); 
     ImageList deviceImageList = new ImageList(); 

     public ConnectDialog() 
     { 
      InitializeComponent();  
     } 

     public ConnectDialog(List<String> ipAddr) 
     { 
      InitializeComponent(); 
      cboNetworkAdapter.Items.AddRange(ipAddr.ToArray()); 
      cboNetworkAdapter.SelectedIndex = 0; 
     } 

     private void ConnectDialog_Load(object sender, EventArgs e) 
     { 
      Bitmap devImage = Properties.Resources.devIcon; 
      deviceImageList.Images.Add(devImage); 
      deviceImageList.ImageSize = new Size(30, 30); 
     } 

     private void cboNetworkAdapter_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      StartWorking(); 
     } 

     private void StartWorking() 
     { 
      prgBarConnect.Value = 0; 
      dictionary.Clear(); 
      lstvwDevIds.Clear(); 
      bkgndWorker = new BackgroundWorker(); 

      bkgndWorker.DoWork += new DoWorkEventHandler(bkgndWorker_DoWork); 
      bkgndWorker.ProgressChanged += new ProgressChangedEventHandler(bkgndWorker_ProgressChanged); 
      bkgndWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bkgndWorker_RunWorkerCompleted); 
      bkgndWorker.WorkerReportsProgress = true; 
      bkgndWorker.RunWorkerAsync(); 
      bkgndWorker.Dispose(); 
     } 

     private void bkgndWorker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      int numDevs = 0; 
      switch (cboNetworkAdapter.SelectedIndex) 
      { 
       case 0: 
        numDevs = 4; 
        break; 
       case 1: 
        numDevs = 1; 
        break; 
       case 2: 
        numDevs = 10; 
        break; 
      } 
      populateImages(numDevs); 
     } 

     void bkgndWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      prgBarConnect.Value = e.ProgressPercentage; 
     } 

     void bkgndWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      foreach (KeyValuePair<String, int> entry in dictionary) 
      { 
       ListViewItem lstViewDevImage = new ListViewItem(entry.Key, entry.Value); 
       lstvwDevIds.Items.Add(lstViewDevImage); 
      } 

      if (lstvwDevIds.SelectedItems.Count > 0) 
       Console.WriteLine(String.Format("Device id: {0}", lstvwDevIds.Items.IndexOf(lstvwDevIds.SelectedItems[0]))); 

      lstvwDevIds.LargeImageList = deviceImageList; 
     } 

     private void populateImages(int numDevs) 
     { 
      for (int i = 1; i <= numDevs; i++) 
      { 
       System.Threading.Thread.Sleep(100); 
       int percents = (i * 100)/numDevs; 

       String lstVwItemDesc = String.Format("Dev {0}", i - 1); 
       dictionary.Add(lstVwItemDesc, deviceImageList.Images.Count - 1); 
       bkgndWorker.ReportProgress(percents, i); 
      } 
     } 
    } 
} 

Success on Form Load

+0

バックグラウンドワーカーを開始した直後に処分していますか? 'DoWorkAsync'は_asynchronously_を実行するので、' DoWork'が終了する前にdisposeコマンドを実行します。 –

答えて

2

あなたが実行しているにしたいBackgroundWorkerの上でのDisposeを呼び出さないでください。あなたのBackgroundWorkerのインスタンスの同じクリーンアップを行うには同様にあなたのフォームにDisposeを実装する場合があります

// if we have an instance of a backgroundworker ... 
// Cancel and Dispose that one 
if (bkgndWorker !=null) 
{ 
    // in case you want to end the DoWork nicely 
    bkgndWorker.CancelAsync(); 
    bkgndWorker.Dispose(); 
} 

// start again 
bkgndWorker = new BackgroundWorker(); 

bkgndWorker.DoWork += new DoWorkEventHandler(bkgndWorker_DoWork); 
bkgndWorker.ProgressChanged += new ProgressChangedEventHandler(bkgndWorker_ProgressChanged); 
bkgndWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bkgndWorker_RunWorkerCompleted); 
bkgndWorker.WorkerReportsProgress = true; 
bkgndWorker.RunWorkerAsync(); 
// removed the call to Dispose 

:代わりにこれを行います。

関連する問題