繁体   English   中英

如何在C#Windows Phone 8中使用等待功能返回数据?

[英]How to return data using await function in C# windows phone 8?

我是C#的新手。 我在C#Windows Phone 8.0中遇到与异步方法和等待功能有关的问题。

我有这个http请求,可以得到答复。 这工作正常,没有问题...

public async static Task<List<MyAccountData>> GetBalance()
{
       HttpClient = new HttpClient();
       string response = await client.GetStringAsync("http://xxxx/xxx/xxx");

       List<MyAccountData> data = JsonConvert.DeserializeObject<List<MyAccountData>>(response);

       return data;
}

我还有另一个类MainModel

public class MainModel
{
       public void LoadData()
       {

       }
}

所以我的问题是,我想在MainModel类中调用带有GetBalance方法,并将数据解析为LoadData方法(只需在LoadData方法中使用2访问数据)。 LoadData方法不能更改返回类型或不能使用async 那怎么可能呢?

在Windows Phone 8开发人员中使用异步等待没有区别:

public class MainModel
{
    public async void LoadData()
    {
        var data = await Foo.GetBalance();
    }
}

取决于您是否要使LoadData同步(直到通过HTTP将所有数据流式传输之前不返回,并且直到那时都锁定UI才返回),还是要开始该过程并立即返回。 如果您无法将LoadData更改为异步,那么这只是您的两个选择。

如果希望LoadData同步:

public void LoadData() {
    var task = GetBalance();
    var result = task.Result; // will lock up the UI until the HTTP request returns
    // now do something with result
}

如果您希望它启动后台进程并立即返回,但是由于某种原因,不想将LoadData标记为async

public void LoadData() {
    BeginLoadData();
}
private async void BeginLoadData() {
    var result = await GetBalance();
    // now do something with result
}

尽管确实如此,但没有理由不让 LoadData异步进行。 async void不会强制您以任何方式更改调用方(与Async<Task<T>> ),并且它与普通的旧的非异步委托兼容。

public async void LoadData() {
    var result = await GetBalance();
    // now do something with result
}
// ...
LoadData(); // works just fine
Action myAction = LoadData; // works just fine

在进行异步操作时,您需要等待操作完成。返回类型async / await方法始终为Task(TResult) ,要访问异步/等待结果,您需要使用Result属性。 Result属性的值可确保异步操作在返回之前已完成。

    public void LoadData()
    {
        var  data = GetBalance().Result;
    }

如果您想要一个响应式UI(即有可能在存储中被接受的UI),那么阻止异步操作就不是一种选择

取而代之的是,您必须考虑一下在操作进行过程中UI的外观。 在考虑这一点的同时,还要考虑如果操作出错,您希望UI如何响应。

然后,您可以编写解决方案。 如果您捕获了所有异常并对其进行了干净处理, 可以使用async void进行此操作:

public async void LoadData()
{
  try
  {
    ... // Set up "loading" UI state.
    var balance = await GetBalanceAsync();

    ... // Set up "normal" UI state.
    Balance = balance;
  }
  catch
  {
    ... // Set up "error" UI state.
  }
}

但是,我更喜欢使用我创建的称为NotifyTaskCompletion的类型,它是Task<T>的数据可绑定包装器(在我的MSDN文章中进行了介绍 )。 使用NotifyTaskCompletionLoadData变得更加简单:

public void LoadData()
{
  GetBalanceOperation = new NotifyTaskCompletion<Balance>(GetBalanceAsync());
}

public NotifyTaskCompletion<Balance> GetBalanceOperation // Raises INotifyPropertyChanged when set

然后,您的UI可以数据绑定到NotifyTaskCompletion<T>上的属性,例如IsNotCompleted (用于“正在加载”状态), IsSuccessfullyCompletedResult (用于“正常”状态)以及IsFaultedErrorMessage (用于“错误”状态) )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM