首页 > 解决方案 > 尝试调用异步方法 - await vs GetAwaiter().GetResult();

问题描述

我正在尝试使用一种方法编写一个类,该方法将从 REST API(用于 youtube 播放列表的 googleapi)获取一些数据并将该数据转储到 ObservableCollection 中。我遇到的问题是当我调用它时:

this.getPlaylistItemsAsync().GetAwaiter().GetResult();

代码执行。

当我这样称呼时:

await this.getPlaylistItemsAsync();

它只是跳过代码。

我对整个异步编程很陌生...我认为我了解基本概念..我只是不知道该怎么做:(

完整代码在这里:

#define DEBUG
//#define TestEnvi

using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Newtonsoft.Json;



namespace IntuifaceYTPlaylist {

public class IFYT_Playlist {
    
    public string playlistID {get;set;}= "PLYu7z3I8tdEmpjIoZHybXD4xmXXYrTqlk";  // The ID with which we identify our playlist
    private string key = "supersecretAPIkey";    // The API-Key we use to access the google-API
    public ObservableCollection<string> videosList {get;set;}= new ObservableCollection<string>();

    public IFYT_Playlist () {
        Console.WriteLine("Class Loaded!");
#if TestEnvi
        this.getPlaylistItemsAsync().GetAwaiter().GetResult();
        Console.WriteLine("This worked!");
        await this.getPlaylistItemsAsync();
        Console.WriteLine("This didn't!"); //In fact this line isn't even executed :(
#endif
    }

#region getData

    public async void update (){
        this.getPlaylistItemsAsync().GetAwaiter().GetResult();
    }

    // Access the REST-API to retrieve the full dataset
    // TODO: Manage connection to the API - DONE
    // TODO: Parse JSON
    public async Task<ObservableCollection<string>> getPlaylistItemsAsync(){

        var output = new ObservableCollection<string>();

        string URL = "https://www.googleapis.com/youtube/v3/playlistItems";
        HttpClient client = new HttpClient();

        string query = URL + "?key=" + this.key + "&part=contentDetails&playlistId=" + this.playlistID + "&maxResults=50";

        var response = await client.GetStringAsync(query);  //Dump the JSON string into an object!

# if DEBUG
        // Dump the response into a file - just so we can check it if something goes wrong...
        using (StreamWriter outputFile = new StreamWriter(Path.Combine("", "Dump.json")))
        {
                outputFile.WriteLine(response);
        }
#endif

        var responseData = JsonConvert.DeserializeObject<dynamic>(response);

        // Iterate over the items in the list to get the VideoIDs of the individual videos
        foreach (var item in responseData.items){
            output.Add(JsonConvert.SerializeObject(item.contentDetails.videoId));
        }
        Console.WriteLine(output);

#if DEBUG   //Let's see if that worked....
        Console.WriteLine();
        Console.WriteLine("Printing VideoIDs:");
        Console.WriteLine();
        foreach (var item in output){
            Console.WriteLine(item);
        }
        Console.WriteLine();
#endif


    this.videosList = output;
    return output;    
    }
#endregion
}

}

我用来调用它的程序如下所示:

using System;
using IntuifaceYTPlaylist;

namespace TestEnvi
{
    class Program
    {
        static void Main(string[] args)
        {            
            Create();
        }

        static async void Create(){
            IFYT_Playlist playlist = new IFYT_Playlist();
            playlist.getPlaylistItemsAsync().GetAwaiter().GetResult();
            Console.WriteLine("This worked!");
            await playlist.getPlaylistItemsAsync();
            Console.WriteLine("Did this?");
        }
    }
}

标签: c#async-await

解决方案


被调用的方法立即返回到调用者(即返回Main),await然后从那里开始,两者(调用者和被调用的方法)同时运行。然而,由于Main先完成,整个程序就结束了。

因此,如果您想等待异步调用完成,您可以更改Create()为 returnTask而不是void然后您可以等待,例如: Create().Wait();


推荐阅读