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.

Другие вопросы по тегам