C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: イベント発生から一定時間置いてから表示を更新したい


(過去ログ 135 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■79759 / inTopicNo.1)  イベント発生から一定時間置いてから表示を更新したい
  
□投稿者/ ゆきした (1回)-(2016/05/13(Fri) 00:19:35)

分類:[C#] 

C#でWindowsフォームアプリを作っております。
ボタンを押すと一定の処理をしてlabelのText表示を更新させたいのですが少しタメを作りたいです。
ちょっと違いますが、めまぐるしくなり過ぎないように麻雀ゲームなどでCOM側が考える時間を取るような感じです。
100ms程度を想定しています。

重い処理をその間に済ませておきたいのと、途中で次の入力が来たらタメを打ち切って次の処理に入りたいのでSleep以外がいいです。
何か丁度いいものはないでしょうか?
引用返信 編集キー/
■79760 / inTopicNo.2)  Re[1]: イベント発生から一定時間置いてから表示を更新したい
□投稿者/ Azulean (640回)-(2016/05/13(Fri) 07:09:39)
No79759 (ゆきした さん) に返信
> 重い処理をその間に済ませておきたいのと、途中で次の入力が来たらタメを打ち切って次の処理に入りたいのでSleep以外がいいです。
> 何か丁度いいものはないでしょうか?

Timer を使うとか、Task を使うとか。非標準の領域であれば Rx を使うとか。
それぞれ調べてみてください。
引用返信 編集キー/
■79761 / inTopicNo.3)  Re[1]: イベント発生から一定時間置いてから表示を更新したい
□投稿者/ kiku (99回)-(2016/05/13(Fri) 09:36:27)

下記を参考にして、BackgroundWorkerを使うのが良いと思います。
http://dobon.net/vb/dotnet/programing/progressdialogbw.html

引用返信 編集キー/
■79762 / inTopicNo.4)  Re[2]: イベント発生から一定時間置いてから表示を更新したい
□投稿者/ とっちゃん (355回)-(2016/05/13(Fri) 11:20:55)
No79759 (ゆきした さん) に返信

> ボタンを押すと一定の処理をしてlabelのText表示を更新させたいのですが少しタメを作りたいです。
> ちょっと違いますが、めまぐるしくなり過ぎないように麻雀ゲームなどでCOM側が考える時間を取るような感じです。
> 100ms程度を想定しています。
>
> 重い処理をその間に済ませておきたいのと、途中で次の入力が来たらタメを打ち切って次の処理に入りたいのでSleep以外がいいです。
> 何か丁度いいものはないでしょうか?

BackgroundWorker が出てたので、別の。TAP(タスクベースの非同期パターン)を使うという形もあります。
4.5 以上なら、async/await を使ってもいいと思います。
ほかの非同期パターンも合わせて
https://msdn.microsoft.com/ja-jp/library/jj152938.aspx
を参考にリンクしておきます。

でも、100ms(0.1秒)程度で帰ってくるなら、タスクにせず
Application.UseWaitCursor = true; で待機カーソルにする(Cursor.Current = Cursors.WaitCursor;でもよい)
重い処理を実行
ラベルを更新
カーソルを戻す(UseWaitCursor = false または Cursor.Current を前の状態に戻すでもよい)
でも十分かと。

また、単純な時間経過だけなら、タイマー(System.Windows.Forms.Timer)を使ってもいいと思います。

引用返信 編集キー/
■79763 / inTopicNo.5)  Re[3]: イベント発生から一定時間置いてから表示を更新したい
□投稿者/ kiku (100回)-(2016/05/13(Fri) 12:06:37)
TAPはあまり使い慣れていないので勉強も兼ねて
BackgroundWorker的なことをやってみました。
※間違えていることもあります。

        CancellationTokenSource ts;

        private async void button2_Click(object sender, EventArgs e)
        {
            ts = new CancellationTokenSource(5000);
            var progress = new Progress<int>(Progress);  // UIスレッド上で実行する必要がある
            await Work(ts.Token, progress);
            label2.Text = "終了";
        }

        async Task Work(CancellationToken token, IProgress<int> progress) 
        { 
            for (;;) 
            { 
                foreach (var value in Enumerable.Range(0, 100)) 
                { 
                    if (token.IsCancellationRequested)
                    { 
                        return; 
                    }
                    await Task.Delay(10); 
                    progress.Report(value); 
                } 
            } 
        } 
        
        void Progress(int Value) 
        {
            label1.Text = Value.ToString();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            ts.Cancel();
        }

引用返信 編集キー/
■79766 / inTopicNo.6)  Re[4]: イベント発生から一定時間置いてから表示を更新したい
□投稿者/ kiku (101回)-(2016/05/13(Fri) 15:02:45)
No79763 (kiku さん) に返信

上記は、どうやら定石ではないようなので、無視してください。
自身なくなった。
引用返信 編集キー/
■79767 / inTopicNo.7)  Re[5]: イベント発生から一定時間置いてから表示を更新したい
□投稿者/ とっちゃん (356回)-(2016/05/13(Fri) 16:36:41)
No79766 (kiku さん) に返信
> ■No79763 (kiku さん) に返信
>
> 上記は、どうやら定石ではないようなので、無視してください。
> 自身なくなった。

非同期処理には、まだ定石と呼べるような定番処理はないと思います。

慣れてないからどうすればいい?というのはあると思いますが

Taskを使うなら、

button2.Enabled = false;
await Task.Run( () =>{ 時間がかかる作業; } ); // Work としていた部分そのもので、時間がかかる作業自身は同期的な書き方でも問題ない
button2.Enabled = true;

でスタートすればいいと思います。
たぶん定石的な書き方とするならこの程度。

あとは、button2 の代わりにトップレベルウィンドウを持ってくるとかそのくらい。

なぜ無効化するのかというところには重要な意味がありますが、あえてここでは触れません。
なぜか?も含めて考えてみるといいかと思います。

引用返信 編集キー/
■79797 / inTopicNo.8)  Re[6]: イベント発生から一定時間置いてから表示を更新したい
□投稿者/ ゆきした (2回)-(2016/05/16(Mon) 22:40:21)
返信遅くなってすみませんでした。
他で忙しくなってまだ試せていませんがとても参考になります。皆さん、ありがとうございます。
進展できたらまたご報告します。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -