Основной поток C # заблокирован вторым потоком с помощью сигнализации? - PullRequest
2 голосов
/ 15 июля 2011

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 ]

3 голосов
/ 16 июля 2011

Ваш основной поток завис, потому что вы вызываете GetFiles() с него.таким образом, у вас есть мертвая блокировка, вот сценарий:

Основной поток будет блокироваться в строке autoEvent.WaitOne(); в ожидании продолжения сигнала, но он никогда не получит этот сигнал, потому что сигнал зависит от выполнениякод в главном потоке "listBox1.Items.Add(number);" и последний будет заблокирован в ожидании завершения autoEvent.WaitOne().мертвая блокировка.

Чтобы исправить это, запустите метод GetFiles() из другого потока, а не из основного потока, поэтому:

ThreadPool.QueueUserWorkItem(new WaitCallback((_) => { GetFiles(); }), null);
1 голос
/ 15 июля 2011

Возможно, вы синхронизируете событие в главном потоке и просто не можете обработать вызовы.

Вы должны опубликовать код, который использует событие позже, в методе GetFiles.

...