【发布时间】:2010-12-17 04:38:14
【问题描述】:
我手头的任务几乎完成了,除了一个问题。我正在尝试通过 beginupdate() 和 endupdate() 通过 backgroundWorker 线程控制列表框 ui 的更新,该线程也用于更新我的进度条。我在想项目列表上的锁或监视器就足够了(在绘制时需要解析列表的情况下),但无济于事。有人有什么想法吗?
这是相关代码...
编辑:显示通过另一个线程将项目添加到列表中。
private void backgroundWorker4_DoWork(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
// Number of intervals
int stop = 60;
for (int i = 1; i <= stop; i++)
{
if (worker.CancellationPending)
{
e.Cancel = true;
backgroundWorker4.ReportProgress(0);
return;
}
//listBoxBeginUpdate(listBox1);
// Half second intervals
//listBox1.BeginUpdate();
//listBox1.EndUpdate();
//ListBox.listBoxBeginUpdate(listBox1);
listBoxBeginUpdate(listBox1);
Thread.Sleep(500);
listBoxEndUpdate(listBox1);
listBoxBeginUpdate(listBox1);
Thread.Sleep(500);
listBoxEndUpdate(listBox1);
// Update every second
//listBoxEndUpdate(listBox1);
int progress = i * 100 / stop;
backgroundWorker4.ReportProgress(progress);
//updateProgressBar = !updateProgressBar;
}
}
public static void listBoxBeginUpdate(System.Windows.Forms.ListBox varListBox)
{
if (varListBox.InvokeRequired)
{
varListBox.BeginInvoke(new MethodInvoker(() => listBoxBeginUpdate(varListBox)));
}
else
{
// Request the lock, and block until it is obtained.
Monitor.Enter(varListBox);
try
{
// When the lock is obtained, add an element.
varListBox.BeginUpdate();
}
finally
{
// Ensure that the lock is released.
Monitor.Exit(varListBox);
}
}
}
public static void listBoxEndUpdate(System.Windows.Forms.ListBox varListBox)
{
if (varListBox.InvokeRequired)
{
varListBox.BeginInvoke(new MethodInvoker(() => listBoxEndUpdate(varListBox)));
}
else
{
// Request the lock, and block until it is obtained.
Monitor.Enter(varListBox);
try
{
// When the lock is obtained, add an element.
varListBox.EndUpdate();
}
finally
{
// Ensure that the lock is released.
Monitor.Exit(varListBox);
}
//lock (varListBox.Items)
//{
// Monitor.Enter(varList
// varListBox.EndUpdate();
//}
}
}
// Added to show the thread adding items into the list
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
Random random = new Random();
//Stopwatch stopwatch = new Stopwatch();
//stopwatch.Start();
while(_threadsRunning)
{
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
System.Threading.Thread.Sleep(1000);
int numberOfItems = random.Next(5, 10);
for (int i = 5; i < numberOfItems; i++)
{
int number = random.Next(1, 10000);
listBoxAddItem(listBox1, number);
}
backgroundWorker1.ReportProgress(numberOfItems);
}
}
public static void listBoxAddItem(System.Windows.Forms.ListBox varListBox, int item)
{
if (varListBox.InvokeRequired)
{
varListBox.BeginInvoke(new MethodInvoker(() => listBoxAddItem(varListBox, item)));
}
else
{
varListBox.Items.Add(item);
}
}
【问题讨论】:
-
列表本身是空白的,尽管您可以看出由于滚动条的增长,项目仍在添加到其中(这是预期的)。直到循环完成后,列表才会重新填充。虽然我只是用 5 秒计时器测试了循环,但它会在大约 4 秒后重新填充。
-
我错过了吗?添加到列表框中的项目在哪里?
-
我故意忽略了它。项目正在通过线程安全庄园中的另一个线程循环添加到列表框,就像调用静态 listBoxBeginUpdate 方法一样。我可以肯定地补充一点,如果它有助于澄清事情的话。
-
我并不完全清楚您要完成什么,但这看起来是一种非常复杂的方法。你到底想做什么?
-
手头的问题是一个复杂的问题,但它是有原因的。编辑:太早不小心按下了输入
标签: c# winforms multithreading