Home > database >  C# Simple app to convert images into Base64 asynchronously
C# Simple app to convert images into Base64 asynchronously

Time:12-16

I'm trying to make a simple winforms app to convert an image to Base64. When debugging I notice that the ui freezes when I click the button to convert to base64, so I started making changes in the code to call the method asynchronously. (It happens that I never used Async methods so I kinda don't know what I'm doing)

My form1.cs code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ImageToBase64
{
    public partial class main : Form
    {
        public main()
        {
            InitializeComponent();
        }

        Util Util = new Util();

        private void button1_Click(object sender, EventArgs e)
        {
            imageDialog.FileName = "";
            imageDialog.Title = "Selecionar Imagem";
            imageDialog.Filter = "JPEG|*.JPG|PNG|*.png";
            imageDialog.ShowDialog();
            imagePathText.Text = imageDialog.FileName;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            imageCode.Text = "";
            Task<string> base64Code = Task.Run(() => Util.ToBase64(imageDialog.FileName));
            imageCode.Text = base64Code.Result;
            
        }
    }
}

My Util.cs code:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ImageToBase64
{
    class Util
    {
        public async Task<string> ToBase64(string img)
        {
            string path = img;
            using (System.Drawing.Image image = System.Drawing.Image.FromFile(path))
            {
                using (MemoryStream m = new MemoryStream())
                {
                    image.Save(m, image.RawFormat);
                    byte[] imageBytes = m.ToArray();
                    string base64String = null;
                    base64String = Convert.ToBase64String(imageBytes);
                    return base64String;
                }
            }
        }
    }
}

Even after these changes the UI still freezes, what can I do to fix that?

CodePudding user response:

First, the code blocks the task. Second, the method ToBase64 ends up producing and encoding the original bytes, assuming nothing is lost due to lossy compression. image.Save(m, image.RawFormat); saves the image data in the original format, so at best it produces the same data.

The code could be reduced to:

private async void button2_Click(object sender, EventArgs e)
{
    //Only needed to provide a visual cue
    imageCode.Text="";
    var bytes=await File.ReadAllBytes(imageDialog.FileName);
    imageCode.Text = await Task.Run(()=>Convert.ToBase64String(bytes));
}

Using an Image would make sense if you wanted to convert the image to a different format before encoding, or if you wanted to encode the raw RGB values

CodePudding user response:

The reason is this

imageCode.Text = base64Code.Result;

.Result will block until the string can be produced, and that is probably not what you want.

You should instead be using async/await:

imageCode.Text = await base64Code;

Note that this requires the method to be marked as async. And you probably also want to catch any exceptions, since they otherwise risk being lost.

I would also recommend using some profiling tools, since these can usually tell you what parts of the code is blocking the UI.

  • Related