After following this question on updating a GUI from another thread I wanted to extend the code slightly so that it worked for something other than property assignment. Specifically I was trying to find a way to assign some functionality directly to a lambda so that I can define the behavior as needed (I modified the original slightly for WPF):
private delegate void UpdateControlThreadSafeDelegate(Control control, System.Linq.Expressions.Expression<Action> property);
public void UpdateControl(Control control, System.Linq.Expressions.Expression<Action> property)
{
// If calling thread is not associated with control dispatcher, call our thread safe property update delegate
if (!control.Dispatcher.CheckAccess())
{
control.Dispatcher.Invoke(new UpdateControlThreadSafeDelegate(UpdateControl), new object[] { control, property });
}
else
{
Action call = property.Compile();
call();
}
}
With usage:
UpdateControl(lbFoo, () => lbFoo.Items.Clear()); // where lbFoo is a ListBox control
This works fine. But I'd rather allow do something like:
UpdateControl(lbFoo, () => { lbFoo.Items.Clear(); lbFoo.Items.Add("Bar");});
This does not work, returning error CS0834: A lambda expression with a statement body cannot be converted to an expression tree. The error is clear, I'm just not certain on how best to proceed. I could follow my original usage and do what I need in several lines, it's just not as tidy.
I'm guessing there is a better/easier way to do what I want.