2011-07-15 115 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的建議在單獨的線程上運行代碼 –