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

标签 c# winforms threadpool autoresetevent

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);
}

最佳答案

您的主线程挂起,因为您正在从中调用 GetFiles()。所以你遇到了死锁,这是一个场景:

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

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

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

关于C# 主线程被第二个线程使用信号阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6709687/

相关文章:

C# 事件处理程序问题

c# - 锁定属性,好方法?

java.lang.OutOfMemory错误: unable to create new native thread message but not a lot of threads running

c# - 如何解决此 Kinect 错误 : Add an AssemblyVersion attribute to 'Microsoft.Kinect.Toolkit.dll'

c# - 如果达到 Sql Server Compact Edition 的限制会怎样?

c# - 如果控制发生变化,如何中断 mouseUp 事件

c# - 在 DataGridView 中只允许选中一个复选框

Java Threadpool TCP 服务器(端口不断变化!!)

c# - ThreadPool.QueueUserWorkItem 的意外行为

C#过滤对象集合