Last active
November 23, 2021 15:31
-
-
Save Tocchann/e2bef36bdd78809d9495e6c8cfbd5d1c to your computer and use it in GitHub Desktop.
レンダリング丸ごと並列化
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 排他制御せずにレンダリングしてもらう(メモリイータータイプ) | |
private ImageSource CreateThumbnail( stirng filePath, Cube.Pdf.Page page ) | |
{ | |
using( var renderer = new DocumentRenderer( filePath ) ) | |
using( var image = renderer.Render( page, page.Size ) ) | |
using( var stream = new MemoryStream() ) | |
{ | |
image.Save( stream, ImageFormat.png ); | |
stream.Seek( 0, SeekOrigin.Begin ); | |
return BitmapFrame( stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad ); | |
} | |
} | |
Task.Run( async ()=> | |
{ | |
var stopwatch = new Stopwatch(); | |
stopwatch.Start(); | |
var thumbnails = new ConcurrentBag<KeyValuePair<int, ImageSource>>(); | |
var generateBitmapSource = new ActionBlock<KeyValuePair<int, Cube.Pdf.Page>>( | |
(kv) => thumbnails.Add( KeyValuePair.Create( kv.Key, CreateThumbnail( filename, kv.Value ) ), | |
new ExecutionDataflowBlockOptions { EnsureOrdered = false, MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded } | |
); | |
foreach(var kv in pages.Select((page, index) => KeyValuePair.Create(index, page))) { | |
await generateBitmapSource.SendAsync(kv); | |
} | |
generateBitmapSource.Complete(); | |
await generateBitmapSource.Completion; | |
foreach(var kv in thumbnails.OrderBy(kv => kv.Key)) { | |
vm.Thumbnails.Add(kv.Value); | |
} | |
stopwatch.Stop(); | |
Debug.WriteLine("Pattern 3: " + stopwatch.ElapsedMilliseconds); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private ImageSource CreateThumbnail( DocumentRenderer renderer, Cube.Pdf.Page page ) | |
{ | |
using( var image = renderer.Render( page, page.Size ) ) | |
using( var stream = new MemoryStream() ) | |
{ | |
image.Save( stream, ImageFormat.png ); | |
stream.Seek( 0, SeekOrigin.Begin ); | |
return BitmapFrame( stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad ); | |
} | |
} | |
Task.Run( async ()=> | |
{ | |
var stopwatch = new Stopwatch(); | |
stopwatch.Start(); | |
// rendererを使いまわす(キューに入れておくことで増えてもなければ作りあれば融通するという使い方をする | |
var rendererQueue = new ConcurrentQueue<DocumentRenderer>(); | |
var thumbnails = new ConcurrentBag<KeyValuePair<int, ImageSource>>(); | |
// タスク自体はコア数よりある程度多いほうが効率よく動く | |
var parallelCount = Environment.ProcessorCount * 2; | |
var generateBitmapSource = new ActionBlock<KeyValuePair<int, Cube.Pdf.Page>>( | |
(kv) => | |
{ | |
if( !rendererQueue.TryDeque( out var renderer ) ){ | |
renderer = new DocumentRenderer( filename ); | |
} | |
thumbnails.Add( KeyValuePair.Create( kv.Key, CreateThumbnail( renderer, kv.Value ) ); | |
rendererQueue.Enqueue( renderer ); | |
}, | |
new ExecutionDataflowBlockOptions { EnsureOrdered = false, MaxDegreeOfParallelism = parallelCount } | |
); | |
foreach(var kv in pages.Select((page, index) => KeyValuePair.Create(index, page))) { | |
await generateBitmapSource.SendAsync(kv); | |
} | |
generateBitmapSource.Complete(); | |
await generateBitmapSource.Completion; | |
foreach(var kv in thumbnails.OrderBy(kv => kv.Key)) { | |
vm.Thumbnails.Add(kv.Value); | |
} | |
stopwatch.Stop(); | |
Debug.WriteLine("Pattern 3: " + stopwatch.ElapsedMilliseconds); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
MaxDegreeOfParallelismに与える数値を変更してなかったので修正。