我有一个简单的应用程序,它使用 async / await(带有异步目标包的 .NET 4.0)与 db 通信并返回结果。
在数据可用之前,我需要更改某些表单元素的行为。对于简单的实现,我想禁用表单元素,直到数据可用。或者改变表单元素上点击事件的行为。
正确的做法是什么?
我想过
- 有一些布尔属性让元素知道线程正在运行。
- 使用事件表单完成工作的按钮?(我怀疑这是解决方案,但请详细说明如何)
谢谢。
我有一个简单的应用程序,它使用 async / await(带有异步目标包的 .NET 4.0)与 db 通信并返回结果。
在数据可用之前,我需要更改某些表单元素的行为。对于简单的实现,我想禁用表单元素,直到数据可用。或者改变表单元素上点击事件的行为。
正确的做法是什么?
我想过
谢谢。
这应该与我们在您的其他问题中看到的代码一样简单。逻辑上你想要:
foo.Enabled = false;
bar.Enabled = false;
// etc
await Task.Run(...);
foo.Enabled = true;
bar.Enabled = true;
现在,如果将需要这种处理的所有控件放在一起,则可以使这变得更简单:
SetEnabled(controlCollection, false);
await Task.Run(...);
SetEnabled(controlCollection, true);
...
private static void SetEnabled(IEnumerable<Control> controls, bool enabled)
{
foreach (var control in controls)
{
control.Enabled = enabled;
}
}
要走的路是使用某种观察者模式。这是最通用的解决方案。
所以:
public interface ObserveDataAvailable {
public void dataIsAvailable(final Data data);
}
public class ObserveDataAvailableComposite {
private final List<ObserveDataAvailable> items = new LinkedList<ObserveDataAvailable>();
public add(final ObserveDataAvailable item) {
items.add(item);
}
public add(final List<ObserveDataAvailable> items) {
this.items.addAll(items);
}
public void dataIsAvailable(final Data data) {
for (final ObserveDataAvailable item : items) {
item.dataIsAvailable(item);
}
}
}
public class ActivateFormelementWhenDataAvailable {
private final FormElement fe;
public ActivateFormelementWhenDataAvailable(final FormElement fe) {
this.fe = fe;
}
public void dataIsAvailable(final Data data) {
fe.set(data);
fe.activate();
}
}
// Run in thread
private void doDataLookup(final ObserveDataAvailable onCompletion) {
final Data data = getDataFromDb();
onCOmpletion.dataIsAvailable(data);
}
现在你可以这样做:
final ObserveDataAvailable onCompletion = new ObserveDataAvailable();
<add the form elements>
runInThread(doDataLookup(onCompletion);