private void cmbPlatform_SelectedIndexChanged(object sender, EventArgs e)
{
string platform = cmbPlatform.Text;
UpcomingGameFinder gameFinder = new UpcomingGameFinder();
Task.Factory.StartNew<IEnumerable<Game>>(() => gameFinder.FindUpcomingGamesByPlatform(platform))
.ContinueWith((i) => PlaceGameItemsInPanel(i.Result));
}
private void PlaceGameItemsInPanel(IEnumerable<Game> games)
{
int yPosition = 0;
foreach (var game in games)
{
GameItem item = new GameItem(game);
item.Location = new Point(0, yPosition);
panelGameItemsHolder.Controls.Add(item);
yPosition += 125;
}
}
Obviously, I’m doing something wrong here, my mind if pretty new to Tasks, so I’m not sure how it would work in this context.
Basically, FindUpcomingGames() takes a long time to finish, I want to grab the returned collection from that method, and create N amount of GameItem objects (which are user controls) and place them in a panel I have in my Windows Forms.
I get this error message:
Cross-thread operation not valid:
Control ‘panelGameItemsHolder’
accessed from a thread other than the
thread it was created on.
Any suggestions?
The PlaceGameItemsInPanel method needs to switch over the UI to interact with UI items. The easiest way to do that is to make your ContinueWith happen on the UI thread. i.e.
This assumes that cmbPlatform_SelectedIndexChanged is happening on the UI thread (which it will be if it’s handling an event from a combo box, as it seems to be here). So you can get a reference to current SynchronizationContext, then use that in the ContinueWith to make sure that runs on the correct SynchronizationContext.
You can read more about this over at http://blogs.msdn.com/b/pfxteam/archive/2009/09/22/9898090.aspx