C
C#2y ago
Anarchist

❔ Are TryAsync methods acceptable?

I've just been refactoring some implementations of a method I have to go from T Load() to bool TryLoad(out T? result), which as far as I'm concerned is not an anti pattern. I was about to do the same for my Task<T> LoadAsync methods but am wondering if this is bad practice and having bool TryLoadAsync(out Task<T?> result) may have some unforeseen consequences?
8 Replies
Angius
Angius2y ago
I mean, if it has to be async, it has to be async
Anarchist
AnarchistOP2y ago
It doesn't have to be, I've got an ILoad and an IAsyncLoad that some classes implement both of so down the line I have the option. It also doesn't have to be a try method, but if there's no issues I think it's a good idea
Angius
Angius2y ago
If a method doesn't do any awaiting inside... why do you want an async version of it?
Anarchist
AnarchistOP2y ago
For context, this is the class. It's a FIleLoader where the user has the option to load a file async or synchronously.
internal class FileLoader : ILoader<string?>, IAsyncLoader<string>
{
private readonly string _path;

public FileLoader(string path)
{
_path = path;
}

public bool TryLoad(out string? data)
{
return TryDoLoad(path => File.ReadAllText(path), out data);
}

public bool TryLoadAsync(out Task<string>? data)
{
return TryDoLoad(path => File.ReadAllTextAsync(path), out data);
}

// Used so reading can optionally be async whilst reusing the rest DoLoad
private delegate T ReadFileFunc<out T>(string path);

private bool TryDoLoad<T>(ReadFileFunc<T?> read, out T? data)
{
data = default;
try
{
data = read.Invoke(_path);
return true;
}
catch (FileNotFoundException ex)
{
Console.WriteLine($"Could not find file at {_path}");
Console.WriteLine(ex);
}
catch (IOException ex)
{
Console.WriteLine($"Failed to read file at {_path}");
Console.WriteLine(ex);
}

return false;
}
}
internal class FileLoader : ILoader<string?>, IAsyncLoader<string>
{
private readonly string _path;

public FileLoader(string path)
{
_path = path;
}

public bool TryLoad(out string? data)
{
return TryDoLoad(path => File.ReadAllText(path), out data);
}

public bool TryLoadAsync(out Task<string>? data)
{
return TryDoLoad(path => File.ReadAllTextAsync(path), out data);
}

// Used so reading can optionally be async whilst reusing the rest DoLoad
private delegate T ReadFileFunc<out T>(string path);

private bool TryDoLoad<T>(ReadFileFunc<T?> read, out T? data)
{
data = default;
try
{
data = read.Invoke(_path);
return true;
}
catch (FileNotFoundException ex)
{
Console.WriteLine($"Could not find file at {_path}");
Console.WriteLine(ex);
}
catch (IOException ex)
{
Console.WriteLine($"Failed to read file at {_path}");
Console.WriteLine(ex);
}

return false;
}
}
Sossenbinder
Sossenbinder2y ago
Try...Async usually breaks once you realize that ref, in and out parameters are not allowed for async methods
Angius
Angius2y ago
Also, not sure how it would work with this delegate That sometimes is async, sometimes isn't
Anarchist
AnarchistOP2y ago
Hmm yeah perhaps this is too problematic, I might just drop the async approach since atm it's a single threaded console app
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server