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

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

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

Re[2]: イメージデータをマルチスレッドで取得する


(過去ログ 157 を表示中)

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

■91412 / inTopicNo.1)  イメージデータをマルチスレッドで取得する
  
□投稿者/ 禿げ (1回)-(2019/06/22(Sat) 11:25:14)

分類:[.NET 全般] 

複数のPNG画像からイメージをマルチスレッドで取得したいのですが、

            Dim ParallelOpt As New ParallelOptions() With {.MaxDegreeOfParallelism = -1}

                    Parallel.For(0, 10001, ParallelOpt,
                             Sub(i As Integer)


                                 Dim bmp1 As New Bitmap(filepath(i))


                                 bmp1.Dispose()
                                 bmp1 = Nothing


                             End Sub)

のようにすると、毎回ではないのですが、
たまに、
Dim bmp1 As New Bitmap(filepath(i))
のところで、

型 'System.OutOfMemoryException' の例外が System.Drawing.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした

追加情報:メモリが不足しています。

となって、プログラムが落ちてしまいます。

コア数が10、スレッド数が20のCore i7 extremeを使用しているのですが、

.MaxDegreeOfParallelism = -1
のところを10とか5に下げると
エラーとなる頻度はかなり落ちます。
しかしそれでもたまにはやはりメモリ不足となってしまいます。

画像ファイルのサイズは
300x300 pixel程度で小さなファイルです。

メモリは32 GB積んでおり、タスクマネージャーを見ても
使用量は4 GB程度となっており、メモリは十分あります。

更に、プログラムはAny CPUで作成しており、64 bitで動作しているので、
2 GBの縛りもありません。

一体、なぜこのようなエラーが生じるのでしょうか?

引用返信 編集キー/
■91413 / inTopicNo.2)  Re[1]: イメージデータをマルチスレッドで取得する
□投稿者/ 禿げ (2回)-(2019/06/22(Sat) 11:49:51)
いま、気づきましたが


Try


Dim bmp1 As New Bitmap(filepath(i))

bmp1.Dispose()
bmp1 = Nothing

Catch ex As Exception


Dim bmp1 As New Bitmap(filepath(i))

bmp1.Dispose()
bmp1 = Nothing



End Try






のようにして、エラーが出た場合でも
再度、トライするようにすると
エラーなく実行できることが分かりました。

こういう使い方って正しいのでしょうか?
Try無しでうまくいく方法があればお教えくださいませ。

引用返信 編集キー/
■91421 / inTopicNo.3)  Re[2]: イメージデータをマルチスレッドで取得する
□投稿者/ とっちゃん (604回)-(2019/06/24(Mon) 11:45:51)
No91412 (禿げ さん) に返信

> 型 'System.OutOfMemoryException' の例外が System.Drawing.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした
>
> 追加情報:メモリが不足しています。
>
> となって、プログラムが落ちてしまいます。
>
> コア数が10、スレッド数が20のCore i7 extremeを使用しているのですが、
>
> .MaxDegreeOfParallelism = -1
> のところを10とか5に下げると
> エラーとなる頻度はかなり落ちます。
> しかしそれでもたまにはやはりメモリ不足となってしまいます。
>
> 画像ファイルのサイズは
> 300x300 pixel程度で小さなファイルです。
>
> メモリは32 GB積んでおり、タスクマネージャーを見ても
> 使用量は4 GB程度となっており、メモリは十分あります。
>
> 更に、プログラムはAny CPUで作成しており、64 bitで動作しているので、
> 2 GBの縛りもありません。
>
> 一体、なぜこのようなエラーが生じるのでしょうか?
>
GDI+ はスレッドセーフにはなっていないと思います(スレッドセーフであると書いていない)。
別スレッドがNGというわけではなく、同時アクセス(Parallel.For はいくつかを同時に処理する)が問題というだけです。

そのため「例外が発生しても、リトライするとうまくいく」というのは
単に失敗しても繰り返すことで、そのうちタイミングがずれて成功するというだけのことだと思います。

ただ、1万ものファイルを Parallel.For() でアクセスしても単純にファイルを読み込むというだけでも
あまり効率いいとは思いません。

並列にファイルリードしても、内部的にはシーケンシャルになるし、HDDだとその都度ヘッドの移動が発生するので
結果的には、シーケンシャルリードよりも時間がかかるということは往々にしてあります。

具体的にどういう処理を行っているかわからないので、どうするのがいいかについては言及できませんが
並列化の方針としてはお勧めできる方向ではないように感じます。


引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -