收到交叉线程异常错误后,我在MSDN上查找了它。
我尝试在那里实现一些代码,但无法使Callback工作。
addItemCallback d = new addItemCallback(addItem);
这位于下面的addItem()方法中。
我正在尝试将项目列表添加到列表框中,最终每次找到一个值时更新表单,而不是在后台程序完成工作时添加所有项目。
private void startWork()
{
progressBar1.Value = 0;
progressBar1.Maximum = 901242;
backgroundWorker1.RunWorkerAsync();
}
private void getList()
{
if (pathFound)
{
for (int i = 0; i < numberOfPaths; i++)
{
Microsoft.Win32.RegistryKey mainPath = secondaryPath.OpenSubKey("application " + Convert.ToString(i));
if (mainPath != null)
{
this.addItem((string)mainPath.GetValue("Name"));
}
backgroundWorker1.ReportProgress(i);
}
}
pathListBox.Sorted = true;
}
private void addItem(string item)
{
if (this.pathListBox.InvokeRequired)
{
//addItemCallback d = new addItemCallback(addItem);
//not sure what this callBack is, can't get it to work, Callback isnt found.
this.Invoke(d, new object[] { item });
}
else
{
this.pathListBox.Items.Add(item);
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
getList();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.progressBar1.Visible = false;
}
远远地工作
代码1.当我使用background_doWork并从中调用方法时,进度条挂起随机点并停止响应,关闭表单时我得到一个对象异常,因为我在关闭表单的同时仍在尝试做的。
代码2.当我将所有代码放在background_doWork中而不是从中调用方法时,进度条有时会工作,每隔一秒或每第3次尝试运行它完成的程序。
导致这种情况的原因是什么?
-----代码1 -----------
public Form1()
{
InitializeComponent();
start();
}
int number = 900000;
public void start()
{
progressBar1.Value = 0;
progressBar1.Maximum = number;
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
getList();
}
private void getList()
{
Microsoft.Win32.RegistryKey mainPath = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node");
for (int i = 0; i < number; i++)
{
Microsoft.Win32.RegistryKey mainPath = secondaryPath.OpenSubKey("application " + Convert.ToString(i));
if (mainPath != null)
{
this.addItem((string)mainPath.GetValue("Name"));
}
backgroundWorker1.ReportProgress(i);
}
}
private void addItem(string item)
{
try
{
if (this.listBox1.InvokeRequired)
{
this.Invoke(new Action<string>(addItem), item);
}
else
{
this.listBox1.Items.Add(item);
}
}
catch
{
MessageBox.Show("Error - Closed Object before it finished working.");
}
//this.steamGamesListBox.Sorted = true;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.progressBar1.Visible = false;
}
------代码2 --------
public Form1()
{
InitializeComponent();
start();
}
int number = 900000;
public void start()
{
progressBar1.Value = 0;
progressBar1.Maximum = number;
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Microsoft.Win32.RegistryKey steamApps64 = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
for (int i = 0; i < number; i++)
{
Microsoft.Win32.RegistryKey steamApps = steamApps64.OpenSubKey("Steam App " + Convert.ToString(i));
if (steamApps != null)
{
this.addItem((string)steamApps.GetValue("DisplayName"));
}
backgroundWorker1.ReportProgress(i);
}
}
private void addItem(string item)
{
try
{
if (this.listBox1.InvokeRequired)
{
this.Invoke(new Action<string>(addItem), item);
}
else
{
this.listBox1.Items.Add(item);
}
}
catch
{
MessageBox.Show("Error - Closed Object before it finished working.");
}
//this.steamGamesListBox.Sorted = true;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.progressBar1.Visible = false;
}
答案 0 :(得分:3)
您需要定义自定义委托类型(addItemCallback
),或者只需使用通用Action
委托:
private void addItem(string item)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new Action<string>(addItem), item);
return;
}
this.pathListBox.Items.Add(item);
}
这通常是最简单的方法,因为您不需要引入其他委托类型。
请注意,object[]
参数是使用params
关键字定义的,因此您不需要实例化新的object
数组,而只需将参数传递给方法。
答案 1 :(得分:0)
添加delegate void addItemCallback(string item);