【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

YOPViewer.NETのデッドロック対策

【注】2010年12月10日以降、仕様変更により利用不可となりました。暗号化のため対応は不可能です。

id:n7shi:20090907のコメントでmmmtokさんからページをめくるときにフリーズするというご指摘がありました。

修正したものを公開します。id:n7shi:20090106の方法により無料のVC# Expressで開発しています。ダウンロードは以下です。

修正箇所

調査したところ、メインスレッドがThread.Join()で待ちに入っているときにサブスレッドから画面の更新のためにInvoke()を発行したため、メインスレッドのイベントキューが処理されずにデッドロックが発生していました。そのため非同期のBeginInvoke()を使用することで対処しました。

PageView.csの最後にあるReadImage()を以下のように修正しました。ぬるぽが発生していることも判明したため、ローカル変数に代入しています。

public void ReadImage()
{
    var t = thread = new SafeThread(Target);
    t.Start(() =>
    {
        PageItem p;
        lock (this) p = page;
        if (p == null) return;
        for (int y = 0; y <= 3; y++)
        {
            for (int x = 0; x <= 3; x++)
            {
                if (t.Thread == null) break;
                if (!p.ReadImage(3, x, y, false)) continue;
                if (t.Thread != null) Target.BeginInvoke((Action)Paint);
            }
            if (t.Thread == null) break;
        }
    });
}