清理调用模式?
问题描述:
现在,我有一个窗口应用程序(C#),吐出长时间运行的报告。每份报告都会从UI中获取一些信息来约束报告。当然,报表创建发生在后台线程上,我需要正确调用各种控件来获取选定索引和值等内容。但我不认为我的代码看起来不错,并希望有更好的模式。因为有这么多要求的控制,我对于将返回各类型进行泛型委托:清理调用模式?
private delegate string StringDelegate();
private delegate int IntDelegate();
再往下,有这些代表的不同实例:
private StringDelegate GetYearSelectedItem = new StringDelegate(cmbYearAsync);
YearAsync看起来是这样的:
private string cmbYearAsync() {
return cmbYear.SelectedItem.ToString();
}
最后,在代码是在后台线程,这是我得到的值:
cmbYear.Invoke(GetCmbYearSelectedItem);
是否有更简单的方法从单独的线程获取这些值?
答
假设您想要使用线程化设计(也许您希望后台线程在运行时向用户界面报告部分结果?),如果您拥有C#3,那么您肯定可以将它稍微整理一下。有些人发现的扩展方法是这样有用:
public static class ControlExtensions
{
public static T Invoke<T>(this Control ctrl, Func<T> func)
{
if (ctrl.InvokeRequired)
return (T) ctrl.Invoke(func);
return func();
}
}
以及检查电话是否需要整理,这也使得委托参数类型安全。所以你可以写:
string selected = comboBox1.Invoke(() => comboBox1.SelectedItem.ToString());
没有必要预先声明所有其他的东西。只需编写您要编写的通用代码,但在该lambda模式中。
对于不需要返回值的操作,您可以编写一个类似的扩展方法,它需要Action
而不是Func<T>
,并返回void
。
答
简短的回答
不要做;-)
长的答案
收集报表参数从UI控件前面(或许在小班),并将其传递给在背景报告边线
这消除了跨线程调用UI控件,和解耦用户界面的报告参数