2012-04-04 37 views
0

我有一個使用線程來更新UI的winform應用程序的問題。我的應用程序確實從雲上傳和下載文件。同時我也在同一個窗口中顯示網絡速度詳情。這三個操作(上傳,下載,顯示n/w速度)由3個不同的線程調用。問題是,當我開始下載/上傳時,整個窗口凍結,n/w速度顯示不刷新(每隔1秒刷新一次)。會有什麼問題?提前致謝。Winform和線程(C#)

代碼如下...同樣的方式我寫下載。如果我先調用**上傳**,然後再下載**,則第一個線程將暫停並下載線程啓動。一旦**下載**完成,然後**上傳**繼續。它不會並行。此外,UI不會立即響應其他按鈕單擊或窗口大小調整,移動操作。

public delegate void UploadDelgt(); 
UploadDelgt UpldDlgtObj; 
private void Form1_Load(object sender, EventArgs e) 
{ 
    UpldDlgtObj = new UploadDelgt(DoUpload); 
} 

public void load() 
{ 
    Form1 form = this; 
    form.Invoke(UpldDlgtObj); 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    thrd = new Thread(new ThreadStart(load)); 
    thrd.Start(); 
    thrd.IsBackground = true; 
} 

public void DoUpload() 
{ 
//uploads file block by block and updates the progressbar accordingly.. 
} 
+3

你應該提供一些代碼。 – adt 2012-04-04 10:13:51

+2

我希望你的代碼沒有做到你認爲的那樣。很難說沒有看到。當然,有些東西會阻止主GUI線程升級標籤。 – Jodrell 2012-04-04 10:14:46

+1

顯示網絡速度等性能數據通常由GUI線程定時器完成,而不是通過線程的通知/信號發送。網絡細節變化太快,無法有效地直接傳達變化信息,並趨向於阻塞GUI輸入隊列 - 無論如何,這對人類來說太快了。 – 2012-04-04 10:26:42

回答

1

你的UI凍結,因爲你在你的load方法調用form.Invoke。從MSDNInvokeExecutes the specified delegate on the thread that owns the control's underlying window handle. 所以,以爲你在一個單獨的線程中調用DoUpload,它仍然在GUI線程(它擁有窗體句柄)上執行,因爲它被調用Invoke

+0

感謝您的回覆。我同意你的意見。但是如果我不使用委託調用,它會拋出CrossThreadOperation異常(因爲我正在更新UI上的進度條)。我發現使用委託是解決方案。那我該如何解決這個問題呢? – 2012-04-05 12:54:17

+1

我建議你直接在一個單獨的線程中調用DoUpload方法(不帶Invoke),並且在這個方法中使用Invoke來更新進度信息。類似[this](http://dotnetpad.net/ViewPaste/U3mHFc3hskmVQUvq8DGmdw#c0,c2,c4,)。只有確保不要過於頻繁地更新UI,否則它仍然會有些滯後。 – 2012-04-05 13:03:24

+0

非常感謝。這解決了我的問題。 – 2012-04-09 11:18:02