c# - 尝试调用异步方法 - 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?");
}
}
}
解决方案
被调用的方法立即返回到调用者(即返回Main
),await
然后从那里开始,两者(调用者和被调用的方法)同时运行。然而,由于Main
先完成,整个程序就结束了。
因此,如果您想等待异步调用完成,您可以更改Create()
为 returnTask
而不是void
然后您可以等待,例如: Create().Wait();
推荐阅读
- python - 为什么这段代码没有实时下载数据?
- kubernetes - 如何通过服务访问 Kubernetes 端口转发?
- javascript - 注册页面上保存的用户名和密码的问题
- java - 为什么即使在添加环境变量后也找不到 mvn -version 的文件错误?
- sql - 将两个表连接在一起并使用包含来自两者的复合键的第三个表?
- python - 无法摆脱旧的 pytest 安装
- oop - 无法在指针接收器结构 golang OOP 中保存指针取消引用
- docker - 如何使用 slack/grafana 或任何其他自动化方式重新启动 docker 容器?
- azure-data-factory-2 - 使用服务主体从 Datafactory 访问 Azure Datalake
- python - 在 GMM 中使用 Dask 代替 Pandas