async Task Replace(StreamReader reader, StreamWriter writer) { Targets.Init(); DateTime lastUpdateTime = DateTime.Now; long cnt = 0; const int chunkSize = 100000; while (true) { var buffer = new char[chunkSize]; var n = await reader.ReadAsync(buffer, 0, buffer.Length); if (n == 0) { break; } cnt += n; Array.Resize(ref buffer, n); await writer.WriteAsync(await Task.Run(() => Replace_SubMethod(buffer))); var time = DateTime.Now; if ((time - lastUpdateTime).TotalSeconds > 0.1) { lastUpdateTime = time; this.Title = $"Processing {cnt} / {reader.BaseStream.Length} ({(100.0 * cnt / reader.BaseStream.Length).ToString("F3")}%)"; } } this.Title = $"OK - {DateTime.Now}"; }
async Task ReplaceMultiThread(StreamReader reader, StreamWriter writer) { await Task.Run(() => { Targets.Init(); DateTime lastUpdateTime = DateTime.Now; long cnt = 0; const int chunkSize = 100000; ThreadPool.SetMaxThreads(50, 50); var runningCount = 1; AutoResetEvent done = new AutoResetEvent(false); Dictionary <int, string> results = new Dictionary <int, string>(); int writeIndex = 0; for (int readIndex = 0; ; readIndex++) { var buffer = new char[chunkSize]; var n = reader.ReadBlock(buffer, 0, buffer.Length); if (n == 0) { break; } cnt += n; Array.Resize(ref buffer, n); var time = DateTime.Now; if ((time - lastUpdateTime).TotalSeconds > 0.1) { lastUpdateTime = time; Dispatcher.Invoke(() => this.Title = $"Processing {cnt} / {reader.BaseStream.Length} ({(100.0 * cnt / reader.BaseStream.Length).ToString("F3")}%)"); } Interlocked.Increment(ref runningCount); ThreadPool.QueueUserWorkItem(new WaitCallback(o => { var result = Replace_SubMethod((char[])((object[])o)[1]); lock (results) { results.Add((int)((object[])o)[0], result); while (results.ContainsKey(writeIndex)) { var str = results[writeIndex]; results.Remove(writeIndex); writer.Write(str); writeIndex++; } } if (0 == Interlocked.Decrement(ref runningCount)) { done.Set(); } }), new object[] { readIndex, buffer }); } if (0 == Interlocked.Decrement(ref runningCount)) { done.Set(); } done.WaitOne(); Dispatcher.Invoke(() => this.Title = $"OK - {DateTime.Now}"); }); }