2011-07-15 59 views
2

GetFiles创建这就要求CopyFiles第二个线程,我只是想每一个文件复制时间填写列表框的文件名,但一旦代码命中行:C#主线程被第二个线程使用信号封锁?

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

没有摄制。它适用于我的机器。 –

+0

@Albert - 你有没有试过不让主线睡着1秒的机会? –

+0

是的,我做了,其实我只是为了测试而设置的,但我在那里做了实际的文件复制操作。 – Albert

回答

3

您的主线程因为您正在调用GetFiles()而被吊死。所以你有一个死锁,这里是一个场景:

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

为了解决这个问题,从另一个线程而非主线程运行GetFiles()方法,所以:

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

谢谢,现在可以运行 – Albert

+0

@Albert:不客气 –

1

或许您正在与主线程上的事件同步,并且它不能处理调用。

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

+0

我添加了一个重要的缺失行GetFiles方法autoEvent.WaitOne(); – Albert

+0

所以你这样陷入了僵局。使用Jalal的建议在单独的线程上运行代码 –