내 작업은 하나의 문제를 제외하고는 모두 완료되었습니다. beginboxdate() 및 endupdate()를 통해 목록 상자 UI의 업데이트를 제어하고 있는데, 이는 진행률 막대를 업데이트하는 데 사용되는 backgroundWorker 스레드를 통해 이루어집니다. 나는 항목 목록에 대한 자물쇠 나 모니터로 충분하다고 생각했지만 (그림을 그릴 때 목록을 분석해야하는 경우) 아무 소용이 없다. 아무도 아이디어가 없나요?멀티 스레드 환경에서 listbox.BeginUpdate/listbox.EndUpdate를 사용하면 작동하지 않습니다.
여기에 편집
... 관련 코드입니다 : 다른 스레드를 통해 목록에 항목의 추가 표시합니다.
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 초 후에 다시 채워졌습니다. – steveng39
누락 되었습니까? 항목이 목록 상자에 추가되는 위치는 어디입니까? –