c# - 如何将代码 YouTube API 从控制台转换为 WPF
问题描述
我的代码在控制台中运行良好,但我尝试将其转换为 WPF c#,但没有成功。我尝试将每个部分移植到 WPF,当我将其转换为 WPF 时,我发现了下面的代码(我在下面引用的第二个代码)它不起作用请帮助我。如何在 WPF c# 中正常工作这是我的代码:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; 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 ConsoleApp2 { internal class PlaylistUpdates { public string PrivacyStatus { get; private set; } [STAThread] static void Main(string[] args) { Console.WriteLine("YouTube Data API: Playlist Updates"); Console.WriteLine("=================================="); try { //new PlaylistUpdates().Run().Wait(); //new PlaylistUpdates().RunUpload().Wait(); new PlaylistUpdates().Editvideo().Wait(); } catch (AggregateException ex) { foreach (var e in ex.InnerExceptions) { Console.WriteLine("Error: " + e.Message); } } Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } private async Task Editvideo() { UserCredential credential; using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read)) { credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, // This OAuth 2.0 access scope allows for read-only access to the authenticated // user's account, but not other types of account access. new[] { YouTubeService.Scope.YoutubeReadonly }, "user", CancellationToken.None, new FileDataStore(this.GetType().ToString()) ); } var youtubeService = new YouTubeService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = this.GetType().ToString() }); var channelsListRequest = youtubeService.Channels.List("contentDetails"); channelsListRequest.Mine = true; // Retrieve the contentDetails part of the channel resource for the authenticated user's channel. var channelsListResponse = await channelsListRequest.ExecuteAsync(); foreach (var channel in channelsListResponse.Items) { // From the API response, extract the playlist ID that identifies the list // of videos uploaded to the authenticated user's channel. var uploadsListId = channel.ContentDetails.RelatedPlaylists.Uploads; Console.WriteLine("Videos in list {0}", uploadsListId); var nextPageToken = ""; while (nextPageToken != null) { var playlistItemsListRequest = youtubeService.PlaylistItems.List("snippet,status"); playlistItemsListRequest.PlaylistId = uploadsListId; playlistItemsListRequest.MaxResults = 50; playlistItemsListRequest.PageToken = nextPageToken; // Create a new, private playlist in the authorized user's channel. var newVideo = new Video(); newVideo.Snippet = new VideoSnippet(); newVideo.Id = "6obQQde1X3A"; newVideo.Snippet.Title = "My Title"; newVideo.Snippet.Description = "My Description"; newVideo.Snippet.Tags = new string[] { "tag 1", "tag 2", "tag 3" }; newVideo.Snippet.CategoryId = "22"; newVideo.Status = new VideoStatus(); newVideo.Status.PrivacyStatus = "public"; newVideo = await youtubeService.Videos.Update(newVideo,"Id,snippet,status").ExecuteAsync(); Console.WriteLine("Change video details OK ...."); // Retrieve the list of videos uploaded to the authenticated user's channel. var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync(); foreach (var playlistItem in playlistItemsListResponse.Items) { Console.WriteLine("{0} ({1})", playlistItem.Snippet.Title, playlistItem.Snippet.ResourceId.VideoId); } nextPageToken = playlistItemsListResponse.NextPageToken; } } } } }
如果我在下面删除此代码。效果很好!
// Create a new, private playlist in the authorized user's channel.
var newVideo = new Video();
newVideo.Snippet = new VideoSnippet();
newVideo.Id = "6obQQde1X3A";
newVideo.Snippet.Title = "My Title";
newVideo.Snippet.Description = "My Description";
newVideo.Snippet.Tags = new string[] { "tag 1", "tag 2", "tag 3" };
newVideo.Snippet.CategoryId = "22";
newVideo.Status = new VideoStatus();
newVideo.Status.PrivacyStatus = "public";
newVideo = await youtubeService.Videos.Update(newVideo,"Id,snippet,status").ExecuteAsync();
Console.WriteLine("Change video details OK ....");
这是我在 WPF 中的代码
private async Task Change_VideoDetails()
{
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { YouTubeService.Scope.YoutubeReadonly },
"user",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
var channelsListRequest = youtubeService.Channels.List("contentDetails");
channelsListRequest.Mine = true;
// Retrieve the contentDetails part of the channel resource for the authenticated user's channel.
var channelsListResponse = await channelsListRequest.ExecuteAsync();
foreach (var channel in channelsListResponse.Items)
{
// From the API response, extract the playlist ID that identifies the list
// of videos uploaded to the authenticated user's channel.
var uploadsListId = channel.ContentDetails.RelatedPlaylists.Uploads;
//Console.WriteLine("Videos in list {0}", uploadsListId);
var nextPageToken = "";
while (nextPageToken != null)
{
var playlistItemsListRequest = youtubeService.PlaylistItems.List("Id,snippet,status");
playlistItemsListRequest.PlaylistId = uploadsListId;
playlistItemsListRequest.MaxResults = 50;
playlistItemsListRequest.PageToken = nextPageToken;
var newVideo = new Video();
newVideo.Snippet = new VideoSnippet();
newVideo.Id = "6obQQde1X3A";
txtLog.AppendText("\nWill change video details....." + newVideo.Id + );
txtLog.ScrollToEnd();
newVideo.Snippet = new VideoSnippet();
newVideo.Id = "6obQQde1X3A";
newVideo.Snippet.Title = "My Title";
newVideo.Snippet.Description = "My Description";
newVideo.Snippet.Tags = new string[] { "tag 1", "tag 2", "tag 3" };
newVideo.Snippet.CategoryId = "22";
newVideo.Status = new VideoStatus();
newVideo.Status.PrivacyStatus = "public";
newVideo = await youtubeService.Videos.Update(newVideo, "Id,snippet,status").ExecuteAsync();
txtLog.AppendText("\nChanged video details ....." + newVideo.Id);
txtLog.ScrollToEnd();
// Retrieve the list of videos uploaded to the authenticated user's channel.
var playlistItemsListResponse = await playlistItemsListRequest.ExecuteAsync();
int line_count=0;
foreach (var playlistItem in playlistItemsListResponse.Items)
{
line_count += 1;
if (line_count == int.Parse(txtVideonumber.Text))
{
break;
}
//}
}
nextPageToken = playlistItemsListResponse.NextPageToken;
}
}
}
我使用下面的代码来运行上面的代码:
private void BtnChange_Click(object sender, RoutedEventArgs e)
{
Change_VideoDetails();
}
我尝试运行调试器,我的代码在以下代码处停止:
newVideo = await youtubeService.Videos.Update(newVideo, "Id,snippet,status").ExecuteAsync();
我不明白为什么它会停止?请帮我解决
解决方案
您必须await
使用异步方法,即await
结果Task
:
// Since this is an event handler 'async void' is allowed.
// Otherwise you must use 'async Task' or 'async Task<T>'
private async void BtnChange_Click(object sender, RoutedEventArgs e)
{
await Change_VideoDetails();
}
等待Task
对于允许正确的异常处理/行为很重要。如果你不这样做await
,Task
那么异常将不会正确传播——异常将被吞没。这是因为在async
方法中异常被捕获并放置在Task
对象上。当您await
使用时Task
,您允许执行传播到调用者的上下文以最终保存您的应用程序或在一个catch
块中处理。
对于无法访问您的环境(包括 Youtube 帐户和身份验证配置)的人来说,您的问题很难解决。
首先确保您的调试器将通过至少启用所有 CLR 异常来中断所有异常:在主菜单中选择Debug/Windows/Exception Setting并选中“Common Language Runtime Exceptions”复选框。
如果在调试器中仍然没有抛出异常,则删除ExecuteAsync()
以同步执行操作。这样您就可以测试是否遇到死锁。当谈到 async/await 时,您必须知道控制台应用程序、Asp.Net 和 Winforms/Wpf/UWP 在某些方面具有不同的行为。
推荐阅读
- testng - 使用默认参数名称的 TestNG 可发送电子邮件报告
- r - 库安装问题 - rlang
- python-3.x - 在python中将字符串日期时间格式化为所需的格式
- python - Tkinter - 从列表中的相应按钮更新文本
- machine-learning - 机器学习中“混合模型”的特点是什么?
- java - 通过 Spring Boot 同时运行多个 CommandLineRunner 是否线程安全?
- mongodb - MongoDB 可以为应用程序分配单独的内存吗?
- google-cloud-firestore - 对我的 firestore 文档的编辑会导致将新的行项目添加到视图/列表中,而不是对原始行项目进行实时更改
- adobe - Adobe Acrobat 图像到 Excel 列对齐
- ios - 最新 ios 中的tone.js 问题