Windows 窗体嵌入式进度条后台工作者
Posted
技术标签:
【中文标题】Windows 窗体嵌入式进度条后台工作者【英文标题】:Windows Form Embedded Progress Bar Background Worker 【发布时间】:2018-02-20 11:38:46 【问题描述】:我想在表单中使用进度条,但遇到了问题。
在表单加载时,进度条完成,列表视图中填充了“已连接”设备的图标。
当我尝试在网络适配器列表中选择另一个索引时,进度条和列表视图会清除,但会引发异常并且 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);
【问题讨论】:
您是否在启动后台工作程序后立即对其进行处理?DoWorkAsync
异步运行,所以它会在DoWork
完成之前执行dispose命令。
【参考方案1】:
不要在要运行的 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
您可能还想在表单上实现 Dispose
以对 BackgroundWorker 实例进行相同的清理。
【讨论】:
以上是关于Windows 窗体嵌入式进度条后台工作者的主要内容,如果未能解决你的问题,请参考以下文章
串口屏开发之滑块控件的使用总结——如何通过滑动滑块实现进度条和文本的联动效果
串口屏开发之滑块控件的使用总结——如何通过滑动滑块实现进度条和文本的联动效果
安装后,Windows 窗体项目未显示来自我的嵌入式 MS Access DB 的任何数据