duotify / slotgames-async

0 stars 1 forks source link

07 請將上週作業加入 CancellationToken 實作 #8

Open doggy8088 opened 4 years ago

doggy8088 commented 4 years ago

Program.cs

using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace SkImageResizer
{
    class Program
    {
        static CancellationTokenSource cts = new CancellationTokenSource();

        static async Task Main(string[] args)
        {
            #region 等候使用者輸入 取消 c 按鍵
            Console.CancelKeyPress += Console_CancelKeyPress;
            static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
            {
                cts.Cancel();
                e.Cancel = true;
            }
            #endregion

            var sourcePath = Path.Combine(Environment.CurrentDirectory, "images");
            var destinationPath = Path.Combine(Environment.CurrentDirectory, "output");

            var imageProcess = new SKImageProcess();

            imageProcess.Clean(destinationPath);

            await imageProcess.ResizeImagesAsync(sourcePath, destinationPath, 2.0, cts.Token);
        }
    }
}

SKImageProcess.cs


public Task ResizeImagesAsync(string sourcePath, string destPath, double scale)
{
    return this.ResizeImagesAsync(sourcePath, destPath, scale, CancellationToken.None);
}

public async Task ResizeImagesAsync(string sourcePath, string destPath, double scale, CancellationToken token)
{
    var allFiles = FindImages(sourcePath);
    var tasks = new ConcurrentBag<Task>();
    foreach (var filePath in allFiles)
    {
        var task = Task.Run(() =>
        {
            var imgName = Path.GetFileNameWithoutExtension(filePath);
            var bitmap = SKBitmap.Decode(filePath);
            var imgPhoto = SKImage.FromBitmap(bitmap);

            var sourceWidth = imgPhoto.Width;
            var sourceHeight = imgPhoto.Height;

            var destinationWidth = (int)(sourceWidth * scale);
            var destinationHeight = (int)(sourceHeight * scale);

            System.Console.WriteLine($"Resizing {filePath} ...");
            using var scaledBitmap = bitmap.Resize(
                new SKImageInfo(destinationWidth, destinationHeight),
                SKFilterQuality.High);
            using var scaledImage = SKImage.FromBitmap(scaledBitmap);
            using var data = scaledImage.Encode(SKEncodedImageFormat.Jpeg, 100);
            using var s = File.OpenWrite(Path.Combine(destPath, imgName + ".jpg"));
            data.SaveTo(s);
            System.Console.WriteLine($"Resizing {filePath} ... Done");
        }, token);

        tasks.Add(task);
    }

    await Task.WhenAll(tasks);
}
shockliang commented 4 years ago
        public async Task ResizeImagesAsync(string sourcePath, string destPath, double scale, CancellationToken ct)
        {
            var allFiles = FindImages(sourcePath);
            var tasks = new ConcurrentBag<Task>();
            var i = 0;
            foreach (var filePath in allFiles)
            {
                i++;
                var j = i;
                var task = Task.Run(() =>
                {
                    var imgName = Path.GetFileNameWithoutExtension(filePath);
                    // Console.WriteLine($"tid: {Thread.CurrentThread.ManagedThreadId} running process image name:{imgName}");
                    var bitmap = SKBitmap.Decode(filePath);
                    var imgPhoto = SKImage.FromBitmap(bitmap);

                    var sourceWidth = imgPhoto.Width;
                    var sourceHeight = imgPhoto.Height;

                    var destinationWidth = (int) (sourceWidth * scale);
                    var destinationHeight = (int) (sourceHeight * scale);

                    using var scaledBitmap = bitmap.Resize(
                        new SKImageInfo(destinationWidth, destinationHeight),
                        SKFilterQuality.High);

                    if (ct.IsCancellationRequested)
                    {
                        Console.WriteLine($"{j} {filePath} IsCancellationRequested");
                        return;
                    }
                    using var scaledImage = SKImage.FromBitmap(scaledBitmap);
                    using var data = scaledImage.Encode(SKEncodedImageFormat.Jpeg, 100);
                    using var s = File.OpenWrite(Path.Combine(destPath, imgName + ".jpg"));
                    data.SaveTo(s);
                }, ct);

                tasks.Add(task);
            }

            try
            {
                await Task.WhenAll(tasks);
            }
            catch (OperationCanceledException oce)
            {
                foreach (var task in tasks)
                {
                    if (task.IsCanceled)
                    {
                        Console.WriteLine($"Task {task.Id}");
                    }
                }
            }
        }