Thursday, September 29, 2011

Safely invoking view-related methods from a controller

Now I've got this situation where I need to call view-refresher stuff from my controller. But the call happens to be inside a background worker. I get a cross thread exception: you can't access stuff that was created on the view thread.

Solution: Invoke it safely:

public void RefreshView()
{
if (this.InvokeRequired)
{
this.Invoke(new UpdateDisplayStateCallback(this.RefreshViewInternally));
}
else
{
this.RefreshViewInternally();
}
}

(RefreshViewsInternally can now contain references to view components you wanted to actually refresh.)

What's that? You want to know how to make your call back method something with parameters? No problem:

public void RefreshViews(ReallyComplexObjectYouCreatedYourself myReallyComplexObjectYouCreatedYourself)
{
if (this.InvokeRequired)
{
this.Invoke(new Action(this.RefreshViewsInternally), myReallyComplexObjectYouCreatedYourself);
}
else
{
this.RefreshViewsInternally(myReallyComplexObjectYouCreatedYourself);
}
}


Now, RefreshViewsInternally is allowed to have this signature: RefreshViewsInternally(ReallyComplexObjectYouCreatedYourself myReallyComplexObjectYouCreatedYourself);

Booya.