Youtube API v3错误 - 挂起等待searchListRequest.ExecuteAsync();

时间:2014-11-12 05:05:43

标签: winforms

我一直在使用Youtube V3 API,但我似乎无法在Windows窗体中使用它。我得到了示例代码,所以我知道我的API密钥正常工作,但是当我尝试从控制台应用程序转换它时,代码挂起就行了,

var searchListResponse = await searchListRequest.ExecuteAsync();

我还没有找到与此问题相关的任何内容,没有编译错误或抛出运行时错误。任何帮助将不胜感激!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data; 
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;

namespace MiddleManYTDL
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            MessageBox.Show("YouTube Data API: Search");

            try
            {
                new Form1().Run().Wait();
            }
            catch (AggregateException exs)
            {
                foreach (var ex in exs.InnerExceptions)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
            }
        }      

        private async Task Run()
        {
          var youtubeService = new YouTubeService(new BaseClientService.Initializer()
          {
              ApiKey = "My API Key",
            ApplicationName = this.GetType().ToString()
          });

          var searchListRequest = youtubeService.Search.List("snippet");
          searchListRequest.Q = "Google"; // Replace with your search term.
          searchListRequest.MaxResults = 10;

          MessageBox.Show("This will Display");
          // Call the search.list method to retrieve results matching the specified query term.
          var searchListResponse = await searchListRequest.ExecuteAsync();
          MessageBox.Show("This never gets executed");

          List<string> videos = new List<string>();
          List<string> channels = new List<string>();
          List<string> playlists = new List<string>();
          // Add each result to the appropriate list, and then display the lists of
          // matching videos, channels, and playlists.
          foreach (var searchResult in searchListResponse.Items)
          {
            switch (searchResult.Id.Kind)
            {
              case "youtube#video":
                videos.Add(String.Format("{0} ({1})", searchResult.Snippet.Title,       
                  searchResult.Id.VideoId));
                break;

              case "youtube#channel":
                channels.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, 
                 searchResult.Id.ChannelId));
               break;

              case "youtube#playlist":
                playlists.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, 
                 searchResult.Id.PlaylistId));
                break;
            }
          }
          MessageBox.Show(String.Format("Videos:\n{0}\n", string.Join("\n", videos)));
          MessageBox.Show(String.Format("Channels:\n{0}\n", string.Join("\n", channels)));
          MessageBox.Show(String.Format("Playlists:\n{0}\n", string.Join("\n", playlists)));
        }
    }
}

1 个答案:

答案 0 :(得分:3)

这与YouTube API无关。您的问题出现在以下行的阻止Wait()调用中:

new Form1().Run().Wait();

正在发生的事情是您的代码到达Run()并同步执行方法的一部分,直到await关键字(在您的情况下 - 在UI线程上)。然后,当await正在进行时,执行将返回到Form.Load处理程序,该处理程序立即命中Wait()调用并阻止UI线程,直到Run()返回任务为止已经完成了。在此之后的某个时刻await内的Run()任务完成,异步状态机尝试在UI线程上执行Run()方法的其余部分。现在你有Wait()阻止UI线程,等待Run()完成,Run()等待UI线程可用,以便{{1}的其余部分方法可以执行。两者都无法取得任何进展。每当async方法与阻止async/awaitWait()调用混合时,此死锁情况就非常常见。

有两种可能的解决方法:

  • 一直使用Result(即在呼叫层次结构中没有阻止async/awaitWait()调用)
  • 重写您的Result方法,以便在Run()之后不会访问任何UI元素,并使用await阻止ConfigureAwait(false)捕获,然后回发到同步安装在UI线程上的上下文(意味着await之后的方法部分将在线程池线程上执行。)

我个人选择#1选项:

await

以下是一些优秀的博客文章,详细讨论了您正在观察的问题:

http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115163.aspx