Right now, I have a windows application (C#) that spits out long running reports. Each report grabs some information from the UI to constrain the reports. Of course, the report creation happens on a background thread and I need to properly invoke the various controls to get things like selected indexes and values. But I don’t think my code looks good and was hoping there was a better pattern. Because there are so many requests to controls, I made generic delegates for each type that would be returned:
private delegate string StringDelegate();
private delegate int IntDelegate();
Further down, there are various instantiations of these delegates:
private StringDelegate GetYearSelectedItem = new StringDelegate(cmbYearAsync);
YearAsync looks like this:
private string cmbYearAsync() {
return cmbYear.SelectedItem.ToString();
}
And finally, in code that is on a background thread, this is how I get the values:
cmbYear.Invoke(GetCmbYearSelectedItem);
Is there a cleaner way of getting these values from a separate thread?
Assuming you want to go with the threaded design (perhaps you want the background threads to report partial results to the UI as they run?), if you have C# 3 you can certainly neaten it up a little. Some people find an extension method like this helpful:
As well as checking whether the call needs to be marshalled, it also makes the delegate parameter typesafe. So you can write:
No need to pre-declare all that other stuff. Just write the usual code you’d write but inside that lambda pattern.
You can write a similar extension method that takes
Actioninstead ofFunc<T>, and returnsvoid, for operations that don’t need a return value.