Returning Task<bool> that involves boolean test for null value of an awaited Task result

dg2k 1,386 Reputation points
2022-08-23T21:21:00.54+00:00

@Viorel , @AgaveJoe , @Michael Taylor thank you for your patience.

This is a simplified version of this question and I am restating the same question with a concise and complete code.

For simple illustration, SecureStorage.GetAsync(string keyName), a well known API (Xamarin and .NET MAUI) for retrieving a stored secret, that is previously saved by SecureStorage.SetAsync(string keyName, string mySecret), is used. See for instance, here.

The following simply tests if an encryption key has been set.

USING ASYNC/AWAIT:

public async Task<bool> IsEncryptionKeySet(string keyName)  
{  
    string secretKey = await SecureStorage.GetAsync(keyName); // if secret by keyName is set, returns a non-null string.  
    return secretKey != null;   // returns true if the key exists.  
}  

I test if an encryption key is set as: bool isSet = await IsEncryptionKeySet("keyName");

RETURNING TASK WITHOUT ASYNC/AWAIT:

public Task<string> GetEncryptionKey(string keyName)  
{  
   return SecureStorage.GetAsync(keyName);   
}  

I can test if an encryption key is set as: bool isSet = await GetEncryptionKey("keyName") != null;

My question is, instead of returning Task<string> and evaluate the Boolean by the caller, is it possible to return Task<bool> of the first form above without using async and await as well as Task.Result or Task.Wait(), thus:

public Task<bool> IsEncryptionKeySet(string keyName)  
{  
    // I'm assuming an async programming may exist to return Task<bool>  
    return Task_StateMachine_Returning(SecureStorage.GetAsync(keyName) != null); // can this be put into code?  
}  

We know that return SecureStorage.GetAsync(keyName) != null); is incorrect as it always returns true (because an awaitable that is pending is always non-null).

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,296 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,280 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 68,656 Reputation points Microsoft Vendor
    2022-08-24T08:12:23.887+00:00

    Hello,

    is it possible to return Task<bool> of the first form above without using async and await

    Yes, you can try to use the following code.

       public  Task<bool> IsEncryptionKeySet(string keyname)  
               {  
                   bool result = false;  
                   var res =  SecureStorage.GetAsync(keyname).Result;  
         
                   if (!string.IsNullOrEmpty(res))  
                   {  
                       result = true;  
                   }  
         
                   return  Task.FromResult(result);  
               }  
    

    But It is recommended to you to achieve it by using async and await. If the value is too long. It will block the UI thread.

       public async Task<bool> IsEncryptionKeySet(string keyname)  
               {  
                   bool result = false;  
                   var res = await SecureStorage.GetAsync(keyname);  
         
                   if (!string.IsNullOrEmpty(res))  
                   {  
                       result = true;  
                   }  
         
                   return await Task.FromResult(result);  
               }  
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


1 additional answer

Sort by: Most helpful
  1. AgaveJoe 26,136 Reputation points
    2022-08-24T13:32:08.34+00:00

    The ContinueWith() method solves this programming problem as explained by cooldadtx in your other thread.

    static async Task<bool> IsEncryptionKeySetAsync(string keyName)  
    {  
        return await SecureStorage.GetAsync(keyName).ContinueWith((key) => { return key.Result != null; });       
    }  
    

    The caller has the following pattern.

    var result = IsEncryptionKeySetAsync("Hello");  
    Console.WriteLine("Do other stuff");  
    Console.WriteLine($"IsEncryptionKeySetAsync = {await result}");  
    

    I just thought there may be more clever ways along the line of return Task.FromResult(<some manipulations here>) that I don't know.

    No. As explained in your other thread, Task.FromResult() wraps a type in a Task. Task.FromResult() is used when you want to bypass executing an asynchronous task but need to return a Task to the caller. For example, returning an item from cache. If the item exists in cache then there is not reason to fetch the item.

    1 person found this answer helpful.