C#主线程被第二个线程使用信令阻塞?

C#主线程被第二个线程使用信令阻塞?,c#,winforms,threadpool,autoresetevent,C#,Winforms,Threadpool,Autoresetevent,GetFiles创建第二个线程,该线程调用CopyFiles,我只是尝试在每次复制文件时用文件名填充列表框,但一旦代码到达行: listBox1.Invoke((MethodInvoker)delegate { PrintProgress(i.ToString()); }, new object[] { }); 主线程被阻塞了,有什么想法吗 void GetFiles() { AutoResetEvent autoEvent = new AutoResetEvent(false);

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);
}
void GetFiles()
{
AutoResetEvent autoEvent=新的AutoResetEvent(假);
QueueUserWorkItem(新的WaitCallback(CopyFiles),autoEvent);
//一些无关的代码
autoEvent.WaitOne();
}
私有void复制文件(对象状态信息)
{
对于(int i=0;i<10;i++)
{
//SetControlPropertyValue(listBox1,i.ToString());
调用((MethodInvoker)委托{PrintProgress(i.ToString());},新对象[]{});
睡眠(1000);
}
//表示此线程已完成。
((AutoResetEvent)stateInfo.Set();
}
私有void打印进度(字符串编号)
{
列表框1.项目.添加(编号);
}

可能您正在与主线程上的事件同步,而它只是无法处理调用


您应该稍后在GetFiles方法中发布使用事件的代码。

您的主线程已挂起,因为您正在从它调用
GetFiles()
。所以你有一个死锁,下面是一个场景:

主线程将在第
autoEvent.WaitOne()行阻塞等待信号继续,但它永远不会收到该信号,因为该信号取决于在主线程“
listBox1.Items.Add(number);
”上执行代码,最后一个将被阻止,等待
autoEvent.WaitOne()
完成。死锁

要修复此问题,请从另一个线程而不是主线程运行
GetFiles()
方法,因此:

ThreadPool.QueueUserWorkItem(new WaitCallback((_) => { GetFiles(); }), null);

没有责备。它在我的机器上工作。@Albert-你有没有试过一次不让主线程休眠1秒?是的,我设置了,事实上我只是为了测试,但我在那里做了实际的文件复制操作。
WaitOne
调用的目的是什么?阻止UI线程任何时间都是一个糟糕的主意;因为我希望主线程等待CopyFiles方法完成其工作,因为GetFiles方法将在autoEvent.WaitOne()之后使用这些文件;我在GetFiles方法autoEvent.WaitOne()中添加了一个重要的缺失行;这样你就陷入了僵局。使用Jalal的建议在单独的线程上运行代码