2

I am trying to determine valid base64 string in async method using codes below:

public static async Task<bool> IsBase64String(string base64)
{
    Span<byte> buffer = new Span<byte>(new byte[base64.Length]);
    return await Task.FromResult(Convert.TryFromBase64String(base64, buffer, out int bytesParsed));
}

But Span can not be declared in async method, any body please help?

Johnny
  • 7,220
  • 1
  • 20
  • 29
Donald
  • 403
  • 1
  • 3
  • 15
  • 1
    Try this approach without the use of Span [link](https://stackoverflow.com/questions/6309379/how-to-check-for-a-valid-base64-encoded-string#21242217) – Giddy Naya Jul 27 '19 at 04:37
  • https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEA3GUCWAZgJ4A+AAgEwCMAsAFDkAMABOdQKwDcD5AzG2pI2lFgGEANgEMAzjJYBvBixVsB7YeQAcbJAB5gECBIB8LAJIyAQrJioAyhgIA7AOYAKdq2C3UASkVlVWCAWRgAW2hiA2IMGDNgAFdCQjwWAF4WZxgAdxYwyKho4Fj492y8kriAbR8ZOxQAOgAZGDcMAAsAXT8eemDg8gB2cQhnXCgMRoAVIoAxKAhwm3qHJ3w3dzqGtBYklLxG+wAHKWddiESMFg3rqpgZAAUpKHqAE16glQBfBm+gA= – user4003407 Jul 27 '19 at 04:44

2 Answers2

3

I am trying to determine valid base64 string in async method

Why? There's nothing asynchronous about that method. The proper way to solve this problem is to remove the async keyword:

public static bool IsBase64String(string base64)
{
  Span<byte> buffer = new Span<byte>(new byte[base64.Length]);
  return Convert.TryFromBase64String(base64, buffer, out int bytesParsed);
}
Stephen Cleary
  • 376,315
  • 69
  • 600
  • 728
2

While Stephen's answer is correct... if you need to use a Span<T> in an async method and you can use C# 7 or above, then you can take advantage of a language feature called local functions to solve for the Parameters or locals of type 'T' cannot be declared in async methods or lambda expressions error. Below is an example of how you could do that... and once again this is meant to solve for the reason given.

using System;
using System.Text;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main(string[] args)
    {
        var base64Str = Convert.ToBase64String(Encoding.UTF8.GetBytes("this is a Base64 str"));
        var notBase64Str = "this is not a Base64 str";
        Console.WriteLine(await IsBase64String(base64Str)); // True
        Console.WriteLine(await IsBase64String(notBase64Str)); // False
    }

    public static async Task<bool> IsBase64String(string base64)
    {
        return await Task.FromResult(CheckIfIsBase64String());
        // Note the use of a local non-async function so you can use `Span<T>`
        bool CheckIfIsBase64String()
        {
            // the use of stackalloc avoids array heap allocation
            Span<byte> buffer = stackalloc byte[base64.Length];
            return Convert.TryFromBase64String(base64, buffer, out int bytesParsed);
        }
    }
}

the code on dotnetfiddle.net

Al Dass
  • 616
  • 10
  • 19
  • it must be an example, but marking a method async and awaiting a Task.FromResult is useless. – Jeroen van Langen Feb 07 '21 at 12:23
  • @jeroen-van-langen given I have `Parameters or locals of type 'T'` this method was given to get around that issue (as my description states). More importantly, how would you do it differently? – Al Dass Feb 07 '21 at 14:35
  • @jeroen-van-langen oh gotcha and yes but, I was trying to match the original post's method signature which is async. – Al Dass Feb 07 '21 at 15:08
  • 1
    You could remove the `async` and the `await`. just return that task directly. By marking the method as `async` it will create another task which is return. Meaning, you're making this method async so it will be split-up into a statemachine and within this statemachine you are awaiting the Task.FromResult. – Jeroen van Langen Feb 07 '21 at 15:09