2016-06-12 60 views
0

因此,我正在尝试编写一个简单的通用应用程序以从网络上获取比特币的价格。我有一个异步方法,我从here得到从一个URL的JSON并将其放入一个字符串。这里就是我所谓的方法:C#Windows通用应用程序未检测到异步方法

 public App() 
     { 
      this.InitializeComponent(); 
      this.Suspending += OnSuspending; 

      CoinPriceBackend CP = new CoinPriceBackend(); 

      string response = await GetFromAPI(); 
     } 

这是方法:

 async Task<string> GetFromAPI() 
     { 
      try 
      { 
       //Create HttpClient 
       HttpClient httpClient = new HttpClient(); 

       //Define Http Headers 
       httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json"); 

       //Call 
       string ResponseString = await httpClient.GetStringAsync(
        new Uri("https://api.bitcoinaverage.com/ticker/GBP/")); 
       //Replace current URL with your URL 

       return ResponseString; 
      } 

      catch (Exception ex) 
      { 
       return "ERROR: " + ex; 
      } 
     } 

我得到的错误

'The 'await' operator can only be used within an async method. 
Consider marking this method with the 'async' modifier and changing its return type to 'Task'.' 

但这种方法异步...如何我能解决这个问题吗?

谢谢!

+2

*“的‘等待’操作只能在**一个异步方法中使用**。“* - 你的'App'构造函数不是。 – IInspectable

回答

0

当您在功能中使用await时,应该将该功能定义为async

但是对于App()构造函数,你将无法做到这一点。你可以定义另一个函数,你可以调用你的函数返回string

像这样

public App() 
{ 
    CallApi(); 
} 

private async void CallApi() 
{ 
    response = await GetFromAPI(); 
} 
+0

任务**是**异步,就是要点 - 这是方法的开场白:异步任务 GetFromAPI() – MattyAB

+0

您没有对App()构造函数使用'async'。但在此范围内,您尝试使用不允许的等待 –

+0

C#中的构造函数不能标记为异步 –

0

C#不允许构造函数被标记为异步。

您有三个主要选项:

1)重构来调用异步事件处理此方法;

2)使用Task.Run产生一个新线程并在那里运行异步代码。这可能会导致将编组结果返回给UI线程并将值分配给某个UI元素;

3)使其同步(阻止)呼叫。这可能是最简单的选择。

您将不得不做出以下更改。

string response = GetFromAPI().Result; 

注意,这可能会导致死锁的任务将尝试reaume在主线程,它已经被调用“结果”锁定,因此,你需要另一个变化。此外,没有一点

Task<string> GetFromAPI() 
{ 
    .... 

    return httpClient.GetStringAsync(new Uri("https://api.bitcoinaverage.com/ticker/GBP/")).ConfigureAwait(false); 

    ... 
} 
1

但这种方法异步

采取在错误消息细看;它不是在谈论GetFromAPI - 它是在谈论App

但是,正如其他人所指出的,构造函数不能将标记为async

我试图写一个简单通用的应用程序

通用的Windows应用程序 - 像所有其他现代平台 - 不能块基于I/O操作的UI线程。用户体验太糟糕了,大多数应用程序商店都有测试来自动拒绝这样做的应用程序。

换句话说:App在应用程序启动时被调用(推测)。当用户启动您的应用程序时,它必须快速启动并显示ASAP。等待下载完成并不是一种选择。

因此,要真正修复这个,你只是需要开始下载(不等待它完成)和你的应用程序初始化为“加载”状态 - 显示一个微调或“载入中... “消息或其他。然后,当下载完成时,更新您的应用程序显示您需要的内容。

我有async constructors博客文章和async MVVM系列文章(如果你做MVVM),但一个非常基本的方法可以是这个样子:

public Task Initialization { get; } 
public string Value { get; private set { /* code to raise PropertyChanged */ } } 

public App() 
{ 
    this.InitializeComponent(); 
    this.Suspending += OnSuspending; 

    CoinPriceBackend CP = new CoinPriceBackend(); 

    Value = "Loading..."; // Initialize to loading state. 
    Initialization = InitializeAsync(); 
} 

private async Task InitializeAsync() 
{ 
    try 
    { 
    string response = await GetFromAPI(); 
    ... 
    Value = response; // Update data-bound value. 
    } 
    catch (Exception ex) 
    { 
    ... // Display to user or something... 
    } 
} 
相关问题