2015-04-22 127 views
2
for (int i = 0; i < someList.length;i++){ 
    Button button = new Button(); 
    // Modify some button attributes height,width etc 

    var request = WebRequest.Create(current.thumbnail); 
    var response = request.GetResponse(); 
    var stream = response.GetResponseStream(); 
    button.BackgroundImage = Image.FromStream(stream); 
    stream.Close(); 

    // and then i have these UI components that need updating (imagePanel is a FlowLayoutPanel) 
    imagePanel.Controls.Add(button); 
    imagePanel.Refresh(); 
    progBar.PerformStep(); 
} 

所以我現在遇到的問題是我用webRequest/Response阻止UI線程。線程完成後的C#更新UI

我猜想我想要做的是在for循環的每次迭代中創建並修改另一個 線程上的按鈕(包括背景圖像)。

當線程完成時有一些回調來更新UI?

另外我可能需要一些方法來將新線程上創建的按鈕返回到主線程以更新UI?

我是c#的初學者,過去沒有真正觸及過任何多線程,難道這是要走的路嗎, 還是我想這些都是錯的。

+3

不要使用線程自己。 BackgroundWorker是一個更好的方法,它包含了一個回調,最終UI線程來處理事情。如果你真的需要使用線程,你可以在需要的時候使用Form的Invoke()方法調用UI線程中的代碼。但先嚐試BGWorker –

+2

也檢查出https://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx –

+0

謝謝,文檔是一個很大的幫助。 – Koborl

回答

6

我會用async/await和Web客戶端來處理這個

await Task.WhenAll(someList.Select(async i => 
{ 
    var button = new Button(); 
    // Modify some button attributes height,width etc 

    using (var wc = new WebClient()) 
    using (var stream = new MemoryStream(await wc.DownloadDataTaskAsync(current.thumbnail))) 
    { 
     button.BackgroundImage = Image.FromStream(stream); 
    } 

    // and then i have these UI components that need updating (imagePanel is a FlowLayoutPanel) 
    imagePanel.Controls.Add(button); 
    imagePanel.Refresh(); 
    progBar.PerformStep(); 
}));