如何将代码 YouTube API 从控制台转换为 WPF
How to convert code YouTube API from Console to 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
对允许适当的例外很重要 handling/behavior。如果您不 await
a Task
那么异常将不会正确传播 - 异常将被吞噬。这是因为在 async
方法中,异常被捕获并放置在 Task
对象上。当您 await
Task
时,您允许执行传播到调用者的上下文以最终保留您的应用程序或在 catch
块中处理。
对于无法访问您的环境(包括 Youtube 帐户和身份验证配置)的人来说,您的问题很难解决。
首先通过至少启用所有 CLR 异常来确保您的调试器将在所有异常上中断:select Debug/ Windows/Exception Setting in the main菜单并选中 “公共语言运行时异常” 复选框。
如果调试器仍然没有异常抛出,去掉ExecuteAsync()
同步执行操作。这样就可以测试是否遇到死锁。说到 async/await 你一定知道控制台应用程序,Asp.Net 和 Winforms/Wpf/UWP 在某些方面有不同的行为。
我的代码在控制台中运行良好,但我尝试将其转换为 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
对允许适当的例外很重要 handling/behavior。如果您不 await
a Task
那么异常将不会正确传播 - 异常将被吞噬。这是因为在 async
方法中,异常被捕获并放置在 Task
对象上。当您 await
Task
时,您允许执行传播到调用者的上下文以最终保留您的应用程序或在 catch
块中处理。
对于无法访问您的环境(包括 Youtube 帐户和身份验证配置)的人来说,您的问题很难解决。
首先通过至少启用所有 CLR 异常来确保您的调试器将在所有异常上中断:select Debug/ Windows/Exception Setting in the main菜单并选中 “公共语言运行时异常” 复选框。
如果调试器仍然没有异常抛出,去掉ExecuteAsync()
同步执行操作。这样就可以测试是否遇到死锁。说到 async/await 你一定知道控制台应用程序,Asp.Net 和 Winforms/Wpf/UWP 在某些方面有不同的行为。