2015-04-22 89 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(); 
}));