質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

1319閲覧

C#でsync(非同期)で取得した文字列をFormのtextboxに書き込みたい。

saki1214

総合スコア36

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2022/08/03 09:32

前提

C#でYoutubeライブのチャットコメントを取得し、Formのtextboxに書き込みたい。
Youtubeライブのチャットコメントは参考記事を使っているが、async(非同期)で書かれている。
チャットコメントは取得できている。

実現したい

C#でsync(非同期)で取得した文字列をFormのtextboxに書き込みたい。

発生している問題・エラーメッセージ

debugモードで変数の中身を見ていると、コメントは取得できているが、textboxに出力されない。

該当のソースコード

参考 https://qiita.com/MCK9595/items/fdbd543ff938febcd136

C#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows.Forms; 10using System.Threading; 11using System.IO.Ports; 12using Google.Apis.Services; 13using Google.Apis.YouTube.v3; 14 15namespace YoutuveLive 16{ 17 public partial class Form1 : Form 18 { 19 public Form1() 20 { 21 InitializeComponent(); 22 } 23 const string APIKey_ = "XXXXXXXXXXXXXXXXXXXXXXXX"; 24 private static Form1 f1; 25 26 private async void button2_Click(object sender, EventArgs e) 27 { 28 await MainStart(); 29 } 30 private void Form1_Load(object sender, EventArgs e) 31 { 32 33 } 34 35 static async Task MainStart() 36 { 37 f1 = new Form1(); 38 var youtubeService = new YouTubeService(new BaseClientService.Initializer() 39 { 40 ApiKey = APIKey_ 41 }); 42 43 string MOVIE_ID = f1.textBoxMovieID.Text; 44 45 string liveChatId = GetliveChatID(MOVIE_ID, youtubeService); 46 while (liveChatId == null || liveChatId == "") 47 { 48 liveChatId = GetliveChatID(MOVIE_ID, youtubeService); 49 } 50 await GetLiveChatMessage(liveChatId, youtubeService, null); 51 } 52 53 static public string GetliveChatID(string videoId, YouTubeService youtubeService) 54 { 55 //引数で取得したい情報を指定 56 var videosList = youtubeService.Videos.List("LiveStreamingDetails"); 57 videosList.Id = videoId; 58 //動画情報の取得 59 var videoListResponse = videosList.Execute(); 60 //LiveChatIDを返す 61 foreach (var videoID in videoListResponse.Items) 62 { 63 return videoID.LiveStreamingDetails.ActiveLiveChatId; 64 } 65 //動画情報取得できない場合はnullを返す 66 return null; 67 } 68 69 static public async Task GetLiveChatMessage(string liveChatId, YouTubeService youtubeService, string nextPageToken) 70 { 71 f1 = new Form1(); 72 var liveChatRequest = youtubeService.LiveChatMessages.List(liveChatId, "snippet,authorDetails"); 73 liveChatRequest.PageToken = nextPageToken; 74 75 var liveChatResponse = await liveChatRequest.ExecuteAsync(); 76 foreach (var liveChat in liveChatResponse.Items) 77 { 78 try 79 { 80 await Task.Run(() => 81 { 82 f1.textBoxLog.AppendText(liveChat.Snippet.DisplayMessage + liveChat.AuthorDetails.DisplayName + System.Environment.NewLine); 83 84 }); 85 } 86 catch { } 87 88 } 89 await Task.Delay((int)liveChatResponse.PollingIntervalMillis); 90 91 await GetLiveChatMessage(liveChatId, youtubeService, liveChatResponse.NextPageToken); 92 } 93 94 }//class 95}//namespace 96

試したこと

async(非同期)を使っているときに、単純にはFormへアクセスできない、ということはわかり、以下のような方法を試しました。

//Errorは出ないが出力はされない f1 = new Form1(); await Task.Run(() => { f1.textBoxLog.AppendText(liveChat.Snippet.DisplayMessage liveChat.AuthorDetails.DisplayName + System.Environment.NewLine); });
//Invokeにたいして、オブジェクト参照が必要です、のError await Task.Run(() => { Invoke(new Action(() => { //Invokeメソッド内ではUIスレッドに戻してくれる f1.textBoxLog.AppendText(liveChat.Snippet.DisplayMessage + liveChat.AuthorDetails.DisplayName + System.Environment.NewLine); })); });

補足情報(FW/ツールのバージョンなど)

C#、Visualstudio

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2022/08/03 10:46

本質問とは直接関係ありませんが、Form1のインスタンスがどうなっているか理解されたほうがよろしいかと思います。
guest

回答3

0

ベストアンサー

Invoke はインスタンスメソッドなので、スタティックメソッドから呼ぶ場合はインスタンスを明示する必要があります。

C#

1await Task.Run(() => 2 { 3 f1.Invoke(new Action(() => 4 (略)

追記

よく見ると大改造が必要です。

(1) private static Form1 f1; は削除
f1 = new Form1(); も消す

(2) スタティックメソッドは static を消してインスタンスメソッドに
f1. ~ は this.~ に変更

(3) this.textBoxLog.AppendText を非同期にするのではなく、
foreach (var liveChat in liveChatResponse.Items) の部分を丸ごと非同期にする

投稿2022/08/03 10:51

編集2022/08/03 11:39
KOZ6.0

総合スコア2626

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saki1214

2022/08/03 11:10

‘‘‘ try { await Task.Run(() => { f1.Invoke(new Action(() => { //Invokeメソッド内ではUIスレッドに戻してくれる f1.textBoxLog.AppendText(liveChat.Snippet.DisplayMessage + liveChat.AuthorDetails.DisplayName + System.Environment.NewLine); })); }); } ‘‘‘ 上記のように変更してみましたが、以下のような例外となりました。 System.InvalidOperationException: 'ウィンドウ ハンドルが作成される前、コントロールで Invoke または BeginInvoke を呼び出せません。'
KOZ6.0

2022/08/03 11:18 編集

f1.Shiow(); してください
YAmaGNZ

2022/08/03 11:21

Form1を新しく作るのが正しいのかという問題があるかと思います
KOZ6.0

2022/08/03 11:25

よくみたら、まともに動かないような気もしますが・・・
saki1214

2022/08/03 11:27

f1.show()すると、書き込まれました。 しかし、これはやりたいこととは違います。 すでにshow()されているform1があるのでこちらのtextboxに書き込みがしたいです。
KOZ6.0

2022/08/03 11:43

> しかし、これはやりたいこととは違います。 自分でそのように組んでるんですよwww 修正箇所を追記しましたので参考にしてください。
saki1214

2022/08/03 11:51

‘‘‘ (1) private static Form1 f1; は削除 f1 = new Form1(); も消す (2) スタティックメソッドは static を消してインスタンスメソッドに f1. ~ は this.~ に変更 ‘‘‘ 追記部分を参考にしたらできました。 (3)については、変更なしでもOKのようです。 もしよろしければ「staticであるかどうか」がどういう影響を与えているのか教えていただけますでしょうか?
KOZ6.0

2022/08/03 12:19

(3) もやってください。 表示される順番が狂ってしまう可能性がありますし、スレッドを起動しまくるのもよくないです。 >もしよろしければ「staticであるかどうか」がどういう影響を与えているのか教えていただけますでしょうか? それを説明するのは難しいです。 「c# 静的メソッド インスタンスメソッド」などでネット検索して調べてみてください。
guest

0

Invokeに対してInvokeにたいして、オブジェクト参照が必要です、のError

this.Invoke としてみたらどうなりますか?

投稿2022/08/03 10:37

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saki1214

2022/08/03 11:15

>静的プロパティ、静的メソッド、または静的フィールド初期化子では無効です。名前を簡略化できます。 となり、VSは不要と言っているようです。
guest

0

別スレッドからGUIコンポーネントを操作する方法ってのはちょっとぐぐればでてきます

投稿2022/08/03 09:48

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2022/08/03 10:31

その方法を使ってるようですが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問