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

わんくま同盟

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

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

■102557 / 1階層)  (追質)時間のかかる処理の進行の表示
□投稿者/ とっちゃん (795回)-(2023/11/17(Fri) 20:50:12)
No102556 (焼いも さん) に返信
> 102521に関連しての追加質問で恐縮です。
> 
> 上が従来ので、下が教えていただいたのを参考にし作ったものです。
> どちらも正常に働き結果も同じなのですが、何故か下にした場合には所要時間がとてつもなく掛かってしまうのです。
> サンプルではシンプルに作ってますが、実際のは結構複雑な計算もしていて、またその結果データの書き込みもしてもいます。
> 何故これほどの時間差が出るのか、ご教授のほどお願い致します。
> 
実際に試したわけでもありませんが、どのくらいの時間差があるのかなどがわかりません。
非同期化しているので、このサンプルのコードの場合であれば
時間がかかるのは、別スレッドで処理している結果、メッセージが処理される分もあると思いますが
毎回 Task をつくって Await するため、作成時間と終了時間と、同期化するための時間、
それと、メッセージ処理がきちんとなされるため(プログレスバーが動いてラベルが変わりますよね?)に
かかる時間とがあるためです。

2000回行っているので、仮に1回あたりの平均が 0.01 秒だったとしても20秒変わってきます。

さて、ではどうするか?というと、Run()をこまめに起こすのではなく、
丸っとひとまとめにして別スレッドで処理する(前回出ていたパターンがこれに該当)か
Dataflowなどを利用してデータ並列(タスク並列)にしていくかのいずれかになります。

処理の具体的な内容がわからないのでどちらが良いかなどは言えませんが一応改めて
今回のサンプルコードをきれいにスレッドアウトしたパターンを提示しておきます。

参考程度にこれだとどの程度変わるか試してみてください。


Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    ' 前処理(ProgressBar1, Label1 は自分の所有物なのでほかの人は触れないと思えばいい)
    ProgressBar1.Minimum = 0 : ProgressBar1.Maximum = 2000 : ProgressBar1.Value = 0
    Label1.Text = "0"
    ' Run の中身は丸っと別スレッドで実行される(自分ではない人にお願いしていると思えばよい)
    Await Task.Run(
        Sub()
            Using sr As New System.IO.StreamReader("C:\Users\***\***.csv", System.Text.Encoding.GetEncoding("Shift_JIS"))
                Dim dats As Integer = 0   '処理済み数
                Do While Not sr.EndOfStream
                    Dim dt As String = sr.ReadLine     '1行全てを読み取る

                    System.Threading.Thread.Sleep(100)   'ここに全ての計算や結果データの書き込みもあります。

                    dats = dats + 1
                    Invoke(
                        Sub()
                            ' 別のスレッドからは自分の所有物にアクセスできないので自分でやるために Invoke(自分の処理として呼び出し)してもらう
                            ProgressBar1.Value = dats
                            Label1.Text = dats.ToString()
                        End Sub)
                    If dats = 2000 Then   '一応ここで脱出
                        Exit Do
                    End If
                Loop
                ' sr は Using しているので Close を呼ばなくても問題ない
            End Using
        End Sub)
End Sub

編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←(追質)時間のかかる処理の進行の表示 /焼いも →Re[2]: (追質)時間のかかる処理の進行の表示 /焼いも
→Re[2]: (追質)時間のかかる処理の進行の表示 /WebSurfer
 
上記関連ツリー

(追質)時間のかかる処理の進行の表示 / 焼いも (23/11/17(Fri) 18:27) #102556
(追質)時間のかかる処理の進行の表示 / とっちゃん (23/11/17(Fri) 20:50) #102557 ←Now
│├ Re[2]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/18(Sat) 10:24) #102559
│└ Re[2]: (追質)時間のかかる処理の進行の表示 / WebSurfer (23/11/18(Sat) 15:04) #102562
Re[1]: (追質)時間のかかる処理の進行の表示 / 魔界の仮面弁士 (23/11/17(Fri) 20:56) #102558
  ├ Re[2]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/18(Sat) 10:40) #102560
  │└ Re[3]: (追質)時間のかかる処理の進行の表示 / WebSurfer (23/11/18(Sat) 12:05) #102561
  │  └ Re[4]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/18(Sat) 15:29) #102563
  │    └ Re[5]: (追質)時間のかかる処理の進行の表示 / WebSurfer (23/11/18(Sat) 15:52) #102564
  │      └ Re[6]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/18(Sat) 20:07) #102567
  │        └ Re[7]: (追質)時間のかかる処理の進行の表示 / WebSurfer (23/11/19(Sun) 10:22) #102574
  │          └ Re[8]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/20(Mon) 00:00) #102578
  │            └ Re[9]: (追質)時間のかかる処理の進行の表示 / WebSurfer (23/11/20(Mon) 09:06) #102582
  │              └ Re[10]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/20(Mon) 15:45) #102583
  │                └ Re[11]: (追質)時間のかかる処理の進行の表示 / WebSurfer (23/11/20(Mon) 17:13) #102585
  │                  └ Re[12]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/21(Tue) 00:59) #102588
  └ Re[2]: (追質)時間のかかる処理の進行の表示 / とっちゃん (23/11/19(Sun) 02:11) #102572
    └ Re[3]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/20(Mon) 00:07) #102579
      └ Re[4]: (追質)時間のかかる処理の進行の表示 / とっちゃん (23/11/20(Mon) 01:48) #102581
        └ Re[5]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/20(Mon) 15:47) #102584
          └ Re[6]: (追質)時間のかかる処理の進行の表示 / とっちゃん (23/11/20(Mon) 17:37) #102586
            └ Re[7]: (追質)時間のかかる処理の進行の表示 / 焼いも (23/11/21(Tue) 00:53) #102587 解決済み
              └ Re[8]: (追質)時間のかかる処理の進行の表示 / WebSurfer (23/11/21(Tue) 18:07) #102589 解決済み

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信