前提
Visual Studio 2022 で Windows Forms アプリを .NET 6.0で作成しています。
Timerはデザインのツールボックスから引っ張ってきたものです。
C#でフォームをロードしたときにメインの処理とは別スレッドで現在時刻を1秒ごとに更新して表示するシステムを作っています。
スレッドスタート→スレッド内でTime_Tickのスタートを行い画面の表示までは行ったのですが、肝心の画面表示後に1秒ごとに時間が更新されません。
こちら解決策等ございますでしょうか…。
ご教示いただけますと幸いです。
実現したいこと
・別スレッドでyyyy/MM/dd HH:mm:ssの形式でラベルに対して1秒ごとに時刻を表示したい
発生している問題・エラーメッセージ
画面表示後に現在時刻が1秒ごとに更新されない
該当のソースコード
private void Form1_Load(object sender, EventArgs e) { DateTime time = DateTime.Now; lblTime.Text = String.Format(time.ToString("yyyy/MM/dd ") + time.ToLongTimeString()); Thread timerClock = new Thread(new ThreadStart(TimerThread)); timerClock.Start(); //後続処理 } private void TimerThread() { Timer1.Interval = 1000;//1秒ごとに更新 Timer1.Start();//Timer1_Tickが実行されるはず } private void Timer1_Tick(object sender, EventArgs e) { DateTime time = DateTime.Now; lblTime.Text = String.Format(time.ToString("yyyy/MM/dd ") + time.ToLongTimeString()); } }
試したこと
1.lblTimeに現在時刻を表示し1秒ごとに更新(フォーマットは「yyyy/MM/dd HH:mm:ss」)を別スレッドで行いたいので、Timer_tickイベントを実行するスレッド「TimerThread」を作成
2.TimerThreadをフォームロードイベント内でnewしてスレッドをStart()で実行→TimerThread内のTimer1.Start();で画面が表示されたのですが、Timer1_Tickのイベントが始まらず、画面上の現在時刻が更新されません。
timer1のイベントハンドラは設定されたのでしょうか?
timer1がどのようなタイマーか分かりませんが、別スレッドで開始したからと言ってイベントは別スレッドで発生するような作りになっているのでしょうか?
また、コントロールを触るのでしたら結局UIスレッドで実行しないといけないわけですがどのようにお考えなのでしょうか?
すみません、スレッド内のtimer1はTimer1でした。
Timer1.Start();でTimer1_Tickイベントが実行されるイメージです。
何を何で作っているかぐらいは書けませんか? (例: Visual Studio 2022 で Windows Forms アプリをターゲットフレームワーク .NET Framework 4.8 で作っています)
それから、Timer と言っても、System.Threading, System.Timers, System.Windows.Forms, System.Web.UI 名前空間に属するものなどいろいろありますが、何なのかを書きましょう。
>何を何で作っているかぐらいは書けませんか?
Visual Studio 2022 で Windows Forms アプリを .NET 6.0で作成しています。
>それから、Timer と言っても、System.Threading, System.Timers, System.Windows.Forms, System.Web.UI 名前空間に属するものなどいろいろありますが、何なのかを書きましょう。
すみません、初学者のためあまり詳しくはわからないのですが、Timerはデザインのツールボックスから引っ張ってきたものです。
上記は追加情報として質問欄を編集して追記願います。ここはコメント欄ですし、初期画面では閉じているので見ない人もいますので。
こちらのサイトの使い方をあまりわかっておらず申し訳ございません。
いま追記いたしました。
> Timerはデザインのツールボックスから引っ張ってきたものです。
であれば、その Timer は System.Windows.Forms 名前空間のもので、Microsoft のドキュメントによると "Timer は、ユーザー定義の間隔でイベントを発生させるために使用されます。この Windows タイマは、UI スレッドを使用して処理を実行するシングルスレッド環境に合わせて設計されています" ということで、UI スレッドでないと動かない(別スレッドでは動かない)と思うのですが?
UI スレッドは、ひとつのプロセスでひとつしか存在が許されていないわけではなく、複数作っても問題ありません。
Application クラスはマルチスレッドに対応しています。
個々のスレッドが独立して動いているぶんには問題ありません。
「シングルスレッド環境に合わせて設計されています」というのは、「別スレッドから操作されることを想定して作っていませんよ。」ということです。
問題が発生するのは、他のスレッドで作成されたコンポーネントを操作したときです。
もっとも、そういう話をするまでもなく、質問で提示されたコードでは、Timer1.Start(); したあとスレッドが終了しているので動くわけはありません。
質問者さん、その後無言ですが、回答が出ているのでそれらに対するフィードバックを返してください。役に立った/立たなかったぐらいはすぐに返せるのでは? 役に立たなかったならどこがダメかを書くとより期待に近い回答が出てくるかも。とにかく無言は NG です。
