C# основной поток заблокирован вторым потоком с помощью сигнализации?
GetFiles
создает второй поток, который вызывает CopyFiles
Я просто пытаюсь заполнить список с именем файла каждый раз, когда файл копируется, но как только код попадает в строку:
listBox1.Invoke((MethodInvoker)delegate { PrintProgress(i.ToString()); }, new object[] { });
основная тема блокируется, есть идеи?
void GetFiles()
{
AutoResetEvent autoEvent = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(new WaitCallback(CopyFiles),autoEvent);
//some unrelated code
autoEvent.WaitOne();
}
private void CopyFiles(object stateInfo)
{
for (int i = 0; i < 10; i++)
{
//SetControlPropertyValue(listBox1, i.ToString());
listBox1.Invoke((MethodInvoker)delegate { PrintProgress(i.ToString()); }, new object[] { });
Thread.Sleep(1000);
}
// Signal that this thread is finished.
((AutoResetEvent)stateInfo).Set();
}
private void PrintProgress(string number)
{
listBox1.Items.Add(number);
}
2 ответа
Ваш основной поток завис, потому что вы звоните GetFiles()
от него. так что у вас есть мертвая блокировка, вот сценарий:
Основной поток будет блокироваться в строке autoEvent.WaitOne();
ожидание сигнала, чтобы продолжить, но он никогда не получит этот сигнал, потому что сигнал зависит от выполнения кода в главном потоке "listBox1.Items.Add(number);
"и последний будет заблокирован в ожидании autoEvent.WaitOne()
заканчивать. мертвый замок.
Чтобы исправить это, запустите GetFiles()
метод из другого потока, а не из основного потока, поэтому:
ThreadPool.QueueUserWorkItem(new WaitCallback((_) => { GetFiles(); }), null);
Возможно, вы синхронизируете событие с основным потоком, и оно просто не может обработать вызовы.
Вы должны опубликовать код, который использует событие позже в методе GetFiles.