2

PDFを画像に変換したい。私は Leadtools を使用しており、速度を上げるために、次の方法でマルチスレッドを使用しています。

string multiPagePDF = @"Manual.pdf";
string destFileName = @"output\Manual";
Task.Factory.StartNew(() =>
{
    using (RasterCodecs codecs = new RasterCodecs())
    {
        CodecsImageInfo info = codecs.GetInformation(multiPagePDF, true);
        ParallelOptions po = new ParallelOptions();
        po.MaxDegreeOfParallelism = 5;
        Parallel.For(1, multiPagePDF.TotalPages+1, po, i =>
        {
            RasterImage image = codecs.Load(multiPagePDF, i);
            codecs.Save(image, destFileName + i + ".png", RasterImageFormat.Png, 0);
         });  
    }       
});

これはスレッドセーフな方法ですか?予期しない出力が発生しますか? これを数回試したところ、特定のページが出力画像に 2 回表示される場合がありました。

解決

Leadtools のオンライン チャット サポート (これは非常に役に立ちます) によると、Rastercodecs.load はスレッド セーフではなく、上記のコードは予期しない出力になります (私の場合、ページ 1 は出力セットの画像で 2 回発生しました)。解決策は、Parallel.For 内で codecs 変数を定義して、反復ごとに独自の RasterCodec に個別にアクセスすることです。

4

1 に答える 1

3

Amyn さん、お気づきのように、この場合の RasterCodecs オブジェクトの正しい使用方法は次のとおりです。

Task.Factory.StartNew(() =>
{
   using (RasterCodecs codecs = new RasterCodecs())
   {
      CodecsImageInfo info = codecs.GetInformation(multiPagePDF, true);
      ParallelOptions po = new ParallelOptions();
      po.MaxDegreeOfParallelism = 5;
      Parallel.For(1, info.TotalPages + 1, po, i =>
      {
         using(RasterCodecs codecs2 = new RasterCodecs()) {
           RasterImage image = codecs2.Load(multiPagePDF, i);
           codecs2.Save(image, destFileName + i + ".png", RasterImageFormat.Png, 0);
         }
      });
   }
});

これにより、同時スレッド間の競合を引き起こすことなく、マルチコア プロセッサで実行する場合と同じ速度の利点が得られます。

LEADTOOLS RasterCodecs.Load() および RasterCodecs.Save() メソッドはスレッドセーフです。RasterCodecs クラスの複数のインスタンスを作成する理由は、このクラスがファイルのさまざまな読み込みおよび保存オプションを保持する構造を内部的に使用するためです。これらの構造 (これらのオプションが変更された場所) を複数のスレッドで使用すると、予期しない結果が生じる可能性があります。読み込みオプション構造体のそのようなプロパティの 1 つがページ番号です。このため、このクラスの個別のインスタンスを使用することをお勧めします。

于 2014-09-19T20:20:35.420 に答える