Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async TryParse(...) pattern

Tags:

c#

async-await

There are a lot of common bool TryXXX(out T result) methods in the .NET BCL, the most popular being, probably, int.TryParse(...).

I would like to implement an async TryXXX() method. Obviously, I can't use out parameters.

Is there an established pattern for this?

More to the point, I need to download and parse a file. It's possible that the file does not exist.

This is what I came up with so far:

public async Task<DownloadResult> TryDownloadAndParse(string fileUri)
{
    try
    {
        result = await DownloadAndParse(fileUri); //defined elsewhere
        return new DownloadResult {IsFound = true, Value = result}
    }
    catch (DownloadNotFoundException ex)
    {
        return new DownloadResult {IsFound = false, Value = null}
    }
    //let any other exception pass
}

public struct DownloadResult
{
    public bool IsFound { get; set; }

    public ParsedFile Value { get; set; }
}
like image 237
Cristian Diaconescu Avatar asked Jun 14 '16 11:06

Cristian Diaconescu


1 Answers

One of possible decisions is an array of ParsedFile, containing 0 or 1 element.

public async Task<ParsedFile[]> TryDownloadAndParse(string fileUri)
{
    try
    {
        return new[] { await DownloadAndParse(fileUri) };
    }
    catch (DownloadNotFoundException ex)
    {
        return new ParsedFile[0];
    }
}

Now you can check the result:

. . .

var parsedFiles = await TryDownloadAndParse(url);
if (parsedFiles.Any())
{
    var parsedFile = parsedFiles.Single();
    // more processing
}

. . .

If you want to call void method, you can use ?. operator:

var parsedFiles = await TryDownloadAndParse(url);
parsedFiles.SingleOrDefault()?.DoVeryImportantWorkWithoutResult();

UPDATE

In Azure you can use ConditionalValue<TValue> class.

like image 117
Mark Shevchenko Avatar answered Oct 05 '22 23:10

Mark Shevchenko