使表单元素等到async / await结束

时间:2012-12-03 07:11:38

标签: c# .net winforms multithreading design-patterns

我有一个简单的应用程序,它使用async / await(带有异步目标程序包的.NET 4.0)与db通信并返回结果。

我需要改变某些表单元素的行为,直到数据可用。对于简单的实现,我想在数据可用之前禁用表单元素。或者更改表单元素上的单击事件的行为。

这样做的正确方法是什么?

我想到了

  • 有一些布尔属性让元素知道线程正在运行。
  • 使用事件来完成工作的按钮? (我怀疑这是解决方案,但请详细说明如何)

感谢。

2 个答案:

答案 0 :(得分:1)

这应该与我们在您的其他问题中看到的代码一样简单。逻辑上你想要:

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;
    }
}

答案 1 :(得分:1)

要走的路是某种观察者模式。这是最通用的解决方案。

所以:

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);