2015-04-22 6 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.C# Update UI After thread Completion

Я предполагаю, что я хочу, чтобы каждая итерация цикла for создавала и изменяла кнопку (включая фоновое изображение) на другую нить.

И когда поток завершен, есть своего рода обратный вызов для обновления пользовательского интерфейса?

Также мне, возможно, понадобится какой-то способ вернуть кнопку, созданную в новом потоке, в основной поток, чтобы обновить интерфейс?

Я новичок в C# и на самом деле не затронул какую-либо многопоточность в прошлом, будет ли это способ обойти это, или я думаю об этом все неправильно.

+3

Не используйте резьбу самостоятельно. BackgroundWorker намного лучше, и он включает обратный вызов в конце для потока пользовательского интерфейса для обработки вещей. Если вам действительно нужно использовать потоки, вы можете использовать метод 'Invoke()' Form для вызова кода в потоке пользовательского интерфейса, когда это необходимо. Но сначала попробуйте BGWorker –

+2

Также проверьте https://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx –

+0

Спасибо, документы были большой помощью. – Koborl

ответ

6

Я хотел бы использовать async/await и WebClient, чтобы справиться с этим

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(); 
}));