トップページ > 記事閲覧
ファイル読み込み系のエラー
名前:Karaage 日時: 2022/02/12 08:34

Visual C#でDxlibを使用しています。 ファイルを非同期読み込みすると、読み込み待機用のwhile文からいつまでたっても抜けなくなり、しばらくするとDxlibがコード0で終了してしまうことがあります。 プログラム自体は終了もフリーズもしません。 また、毎回なるわけではなく、頻度はランダムです。 こちらでは原因不明でしたので質問させていただきました。 Dxlibバージョン: 3.23 OS: Windows 10 Pro 21H1 IDE: Visual Studio Community 2022 (64bit) Version 17.0.6 言語: C#9.0 問題を確認したコードは以下の通りです。 using static DxLibDLL.DX; namespace hogehoge { public struct GraphHandles { static public int hoge; } public class Hogeclass { var ui_font = CreateFontToHandle("Meiryo UI", 22, -1, DX_FONTTYPE_ANTIALIASING); // 非同期読み込み設定に変更 SetUseASyncLoadFlag(TRUE); GraphHandles.hoge = LoadGraph(@"hoge.png"); while ((GetASyncLoadNum() > 0) && (ProcessMessage() == 0)) { ClearDrawScreen(); DrawStringToHandle(100, 100, "グラフィックロード", 0xFFFFFF, ui_font); ScreenFlip(); } } }
メンテ

Page: 1 |

Re: ファイル読み込み系のエラー ( No.1 )
名前:Karaage 日時:2022/02/12 08:36

Hogeclassのコードが少し間違っていました。実際のコードでは、Hogeclass内のメンバ関数でLoadGraphしています。
メンテ
Re: ファイル読み込み系のエラー ( No.2 )
名前:管理人 日時:2022/02/12 14:27

手元で以下のようなプログラムを組んで、延々と非同期読み込みをしてみましたが、 画面に表示される非同期読み込み回数が 20000 を超えてもエラーは発生しませんでした static void Main() { // ウィンドウモードで起動 DX.ChangeWindowMode(DX.TRUE); // DXライブラリの初期化 if (DX.DxLib_Init() < 0) return; int Counter = 0; int GrHandle = 0; // 非同期読み込みON DX.SetUseASyncLoadFlag(DX.TRUE); // 最初の読み込み GrHandle = DX.LoadGraph(@"Test.png"); // 描画先を裏画面に変更 DX.SetDrawScreen(DX.DX_SCREEN_BACK); // メインループ while( DX.ProcessMessage() == 0 ) { DX.ClearDrawScreen(); // 非同期読み込みが終わっていたら、次の非同期読み込みを開始する if( DX.GetASyncLoadNum() == 0 ) { DX.DeleteGraph(GrHandle); GrHandle = DX.LoadGraph(@"Test.png"); Counter++; } // 非同期読み込みの回数を画面に描画 DX.DrawString(0, 0, "LoadCount : " + Counter.ToString(), DX.GetColor(255, 255, 255)); DX.ScreenFlip(); } DX.DxLib_End(); } よろしければ Karaageさんの環境でも上記のプログラムであれば正常に動作するかお試し頂けないでしょうか? m(_ _)m
メンテ
Re: ファイル読み込み系のエラー ( No.3 )
名前:Karaage 日時:2022/02/12 17:57

そちらのコードは特に問題なく実行できたので、そのコードで色々検証してみたところ、await Task.Delayが原因であることが判明しました。 なのでThread.Sleepを使用していた箇所を、Dxlib初期化前はThread.Sleep、初期化後はDxlibのWaitTimerを使用するようにすることで解決しました。 読み込みを行うより前にawait Task.Delayを使用していると、たまに読み込みできなくなってしまうようです。 ちなみに、最初の一回の読み込みが成功したときは、それ以降に何回読み込んでも問題は発生しません。 Dxlibとawait Task.Delayは相性が悪いのでしょうか? お忙しい中、検証ありがとうございました。
メンテ
Re: ファイル読み込み系のエラー ( No.4 )
名前:管理人 日時:2022/02/13 00:08

> Dxlibとawait Task.Delayは相性が悪いのでしょうか? await Task.Delay については知らなかったのですが、 今少し調べてみた限りでは、相性が悪いと思います DXライブラリはスレッドセーフではなく( 複数のスレッドからDXライブラリの関数が 呼ぶことはできない )、DxLib_Init を呼んだスレッド以外のスレッドからDXライブラリの 関数が呼ばれた場合の動作の保証はできない( 別スレッドから呼ばれた場合、正常に動作する 場合もあるかもしれませんが、正常に動作することは保証していない )のですが、 await Task.Delay が実行されると動作としては 『await Task.Delay が呼ばれたら別スレッドを作成して、そのスレッドに ”指定時間待ってその後に書かれている処理を実行させる”という挙動をして、且つ ”await Task.Delay を呼ぶ処理まで行っていたスレッドは await Task.Delay の処理終了を待たずに 関数を抜けて、呼び出し元関数の続きの処理を行う”』 というもののようで、つまり await Task.Delay の後に書かれた処理は await Task.Delay が実行される 前の行までとは別のスレッドが実行することになるので、DXライブラリの制限である 『複数のスレッドからDXライブラリの関数を呼ぶことはできない』や 『DxLib_Init を呼んだスレッド以外のスレッドからDXライブラリの関数を呼ぶことはできない』 に抵触する動作となるので、正常に動作しない可能性が高く相性が悪い、ということになります
メンテ
Re: ファイル読み込み系のエラー ( No.5 )
名前:Karaage 日時:2022/02/13 13:25

なるほどです。 await Task.Delayだけ別スレッドで実行されると誤解していました。 ありがとうございました!
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存