异步Try(blah)模式 [英] Async Try(blah) pattern

查看:60
本文介绍了异步Try(blah)模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找有关如何处理以下情况的建议.

I'm looking for recommendations on how to handle the following situation.

我正在按照这种模式创建尝试获取一些数据的方法:

I'm creating methods for trying to get at some data, following this pattern:

// Typical pattern
public bool TryBlah(string key, out object value)
{
    // ... set value and return boolean
}

在它们的异步版本上尝试遵循此模式时遇到了一个问题,因为您不能在异步方法上使用out:

I've run into an issue when trying to follow this pattern on they async versions because you cannot use out on async methods:

// Ideal async pattern (not allowed to use an 'out' parameter, so this fails)
public async Task<bool> TryBlah(string key, out object value)
{
    // ... set value, perform some slow io operation, return bool
}

一种解决方法是返回包含您的数据的元组.这适用于返回单个数据类型的方法,如下所示:

One workaround is to return a tuple containing your data. This works for methods that return a single data type like so:

// Tuple version
public async Task<Tuple<bool, object>> TryBlah(string key)
{
    // ... perform some slow io, return new Tuple<bool, object>(...)
}

问题是当您要返回不同的数据类型时.在不使用异步的情况下,您可以创建具有几乎相同签名的几种方法,如下所示:

The issue is when you want to return different data types. Without using async you can create several methods with nearly identical signatures like so:

public bool TryBlah(string key, out byte[] value)
{
    // ...
}
public bool TryBlah(string key, out string value)
{
    // ...
}

太好了.这就是我想要做的.此api非常简单易用(方法名称完全相同,仅更改中传递的数据).

That's great. That's what I'm looking to do. This api is very straightforward and easy to work with (the method names are all the same, only the data that is passed in changes).

不能将out与异步方法一起使用会使此情况变得混乱.

Not being able to use out with async methods messes this up though.

解决此问题的一种方法是返回数据的Tuple.但是,现在您不能拥有几乎相同的方法签名,如下所示:

One way to get around this is to return a Tuple of your data. However now you can't have nearly identical method signatures like the following:

// The suck... the signatures match, but you want to return different values.
// You can't do this:
public async Task<Tuple<bool, byte[]>> TryBlah(string key)
{
    // ...
}
public async Task<Tuple<bool, string>> TryBlah(string key)
{
    // ...
}

这些方法失败,因为它们具有相同的签名.解决此问题的唯一方法是给每个方法起一个不同的名称,如下所示:

Those methods fail because they have the same signatures. The only way to work around this that comes to mind is to give each method a distinct name, like so:

public async Task<Tuple<bool, byte[]>> TryBlahByteArray(string key)
{
    // ...
}
public async Task<Tuple<bool, string>> TryBlahString(string key)
{
    // ...
}

我的问题是,这现在创建了我认为令人讨厌的api,在那里您现在拥有许多不同的方法.是的,这不是什么大问题,但我认为必须有更好的方法.

My issue is that this now creates what I consider a nasty api where you now have a whole lot of different methods. Yes, it's not that big of an issue, but I feel that there has to be a better way.

在使用类似这样的异步方法时,是否还有其他模式可以使它们适合更好的api?我愿意接受任何建议.

Are there other patterns that lend themselves to a nicer api when working with async methods like this? I'm open to any suggestions.

推荐答案

也许您可以使用Action<T>作为out param替代品

Maybe you could use Action<T> as the out param substitute

示例:

public async Task<bool> TryBlah(string key, Action<int> value)
{
    int something = await DoLongRunningIO();
    value(something)
    return true;         
}

用法:

int myOutParam = 0;
if (await TryBlah("Something", value => myOutParam = value))
{
    // do somthing
}

这篇关于异步Try(blah)模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆