0

I have created a method to gather entropy for my application.
I've put this in a Task to provide an asynchronous operation for the caller.
I want to avoid a forever loop when collecting entropy from the sensors so I used a timeout which defaults to using RNGCryptoServiceProvider.GetBytes() method.

public Task<byte[]> GetEntropy1(int length)
{
    RNGCryptoServiceProvider entropyGen = new RNGCryptoServiceProvider();
    byte[] entropyBuffer = new byte[2048];

    try
    {
        semaphore.Wait();

        Task t = Task.Run(() =>
        {
            /* gather entropy from sensors */
        });

        if (!t.Wait(5000))
        {
            entropyGen.GetBytes(entropyBuffer);
        }
        return entropyBuffer;
    }
    catch (Exception)
    {
        return entropyBuffer;
    }
    finally
    {
        this.semaphore.Release();
    }
}

But I don't understand why when I return the byte array, I get a warning about implicit cast.
Cannot implicitly convert type 'byte[]' to 'System.Threading.Tasks.Task'

If I use an async in the function definition, then that warning goes away.

  • 2
    Because when you await, you get the result of the task (byte[]) and without it, you get the task itself. It's how it works – BytesOfMetal Feb 22 '19 at 07:13
  • 1
    Does "gather entropy from sensors" return a Task? If so, then await it instead of using Task.Run. As it stands, there is nothing asynchronous about your method, so no point in using tasks. – StuartLC Feb 22 '19 at 07:14
  • The entropy gathering may involve a `while..loop` (still looking into it). I wanted to timeout to avoid it not exiting for whatever reason. – just_another_engineer Feb 22 '19 at 07:21
  • @Petaflop So by having the `async` in the function signature, but without using `await()` in my method, this allows me to return the result rather than the Task object? – just_another_engineer Feb 22 '19 at 07:25
  • @just_another_engineer `async` keyword does nothing by itself. This answer and Stephen's link to his blog may help you to understand how it works: https://stackoverflow.com/a/14178317/6009117 – BytesOfMetal Feb 22 '19 at 08:40

1 Answers1

0

Because async involves the compiler re-writing your method and one of the things it does is to wrap return values in a Task. Without it, no re-writing occurs, and as the error says, a byte[] isn't a Task<byte[]>.

You could write Task.FromResult() at each of your return points1 to do your own manual wrapping.


1Although once you remove the nasty catch clause that's just going to hide errors from you later, you'll only have one anyway.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448