如何在异步方法中使用Span <byte>?

时间:2019-07-27 04:26:28

标签: c#

我正在尝试使用以下代码在异步方法中确定有效的base64字符串:

     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));
    }

但是Span不能在异步方法中声明,任何主体都可以帮助吗?

3 个答案:

答案 0 :(得分:0)

  

我正在尝试在异步方法中确定有效的base64字符串

为什么?该方法没有什么异步的。解决此问题的正确方法是删除async关键字:

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

答案 1 :(得分:0)

Stephen's answer是正确的... 如果,您需要Span<T>方法中使用async并且您可以使用C#7或更高版本,然后可以利用称为local functions的语言功能来解决Parameters or locals of type 'T' cannot be declared in async methods or lambda expressions错误。下面是如何执行此操作的示例...再次说明是为了解决给出的原因。

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()
        {
            var buffer = new Span<byte>(new byte[base64.Length]);
            return Convert.TryFromBase64String(base64, buffer, out int bytesParsed);
        }
    }
}

the code on dotnetfiddle.net

答案 2 :(得分:0)

例如,如果您观察 System.IO.Stream 方法,您会看到,同步方法 Stream.Read()Stream.Write() 接受 Span<byte>,异步方法 Stream.ReadAsync() 和 { {1}} 接受 Stream.WriteAsync()。因此,如果您使用的是真正的异步方法,则不需要创建 Memory<byte>

在您的情况下,您不需要将结果包装在 Span<> 中。该操作将同步完成并将写入 Task。因此,当您将其包装在 TaskTask 中时,您实际上是在说“将此结果包装在任务中,然后将任务的结果给我。”。

但如果您真的想从您的方法中返回 await,您可以删除 Taskasync 关键字。该方法仍然可以从外部等待。 (同样:在这种情况下,不需要将结果包装在 await 中)

Task