我发现自己编写的包装函数纯粹是为了等待异步函数。如何避免这种模式?

时间:2016-03-29 23:04:12

标签: c# asynchronous mvvm async-await

我是C#中异步编程的新手。我使用异步的动机是避免在win表单应用程序中锁定UI线程,而不需要使用一堆后台工作程序或显式线程等。无论如何,这是我目前的理解。

为了等待一个等待函数,调用函数需要是异步的。好吧,我发现自己经常使用以下模式...

public class SomeViewModel
{
  private Thing m_thing;

  public SomeViewModel()
  {
    ReloadThing();
  }

  public Thing Thing
  {
    get {
      return m_thing;
    }

    protected set {
      m_thing = value;
      NotifyPropertyChanged();
    }
  }

  public async void ReloadThing()
  {
     Thing = await FetchThing();
  }

  private async Task<Thing> FetchThing()
  {
    // entity framework code
    return await DbSet<Things>.SingleAsync();
  }
}

基本上一些黑客攻击一起尝试我的视图(Form)的MVVM样式视图模型。

但是,模式是异步包装函数,所以我可以使用await。我应该在这里使用更好的方法吗?

2 个答案:

答案 0 :(得分:4)

  

我想总的问题是,在这样的视图模型中是否有更直接的方式以非阻塞方式加载数据,因此视图(win form)可以绑定到该异步支持的属性数据?这是关于我最具体的问题。

您可能会发现async data binding上的文章很有用。在其中,我为['middleware' => ['web']]引入了一个数据可绑定包装器,它删除了许多关于具有异步代码更新数据绑定(以及正确处理错误情况等)的样板代码。

该代码的更新版本为on GitHub

答案 1 :(得分:0)

Async很烦人。一旦一个方法是异步的并且你想要等待它,那么强制下一个方法,下一个方法,以及下一个方法也使用异步,直到你:a)到达顶部或b)找到你和的地方#39;愿意Wait()

我不认为你做错了什么;除此之外,您不需要FetchThing()来完成您的示例。但我不确定你是否有FetchThing只是为了说明这一点。如果没有,您可以将FetchThing()的正文与ReloadThing()结合起来制作如下:

public async void ReloadThing()
{
   Thing = await DbSet<Things>.SingleAsync();
}

否则,你所看到的对我来说是正确的。