Home > Blockchain >  C# Delegate and async
C# Delegate and async

Time:07-20

I have the following code:

private void LoadImage() {
   (...some irrelevant code...)
   LoadIm = (obj) => {
      var img = new Image();
      img.Source = new StreamImageSource() {
         Stream = (token) => getstream(token)
      };
   };
   (...some other irrelevant code...)
}

private async Task<Stream> getstream(object token) {
   return new MemoryStream(someBytes);
}

It works fine but produces an annoying compile time warning: "This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread."

What's the proper way to handle it? The StreamImageSource expects an async, so I can't make getstream() synchronous.

Thanks in advance.

CodePudding user response:

You'll want to remove async from your method and return Task.FromResult since you're not actually doing any async work:

private Task<Stream> getstream(object token) {
   return Task.FromResult<Stream>(new MemoryStream(someBytes));
}

Next you need to call it correctly so that everything works. You can do one of two things:

  1. Change the signature of your method to match the delegate and assign it directly:
private Task<Stream> getstream(object token)

becomes

private Task<Stream> getstream(CancellationToken token)

with the following assignment

img.Source = new StreamImageSource() {
    Stream = getstream
};
  1. Add async and await to your current code:
img.Source = new StreamImageSource() {
    Stream = async (token) => await getstream(token)
};

CodePudding user response:

Your getstream method is synchronous and returns an instance of type MemoryStream.

If it should return a Task, wrap the result to Task with the static method Task.FromResult:

private async Task<Stream> getstream(byte[] someBytes) {
   return Task.FromResult<Stream>(new MemoryStream(someBytes));
}

The Stream property of the Xamarin.Forms.StreamImageSource class is of type Func<CancellationToken,Task>.So set it to the delegate like this (I assume that you have previously declared and filled someBytes objects):

            ...
            var img = new Image();
            img.Source = new StreamImageSource()
            {
                   Stream = (token) => getstream(someBytes)
            };
            ...

  • Related