同步函数内的异步调用

2023-11-21

我正在尝试异步填充我的缓存

static ConcurrentDictionary<string, string[]> data = new ConcurrentDictionary<string, string[]>();

public static async Task<string[]> GetStuffAsync(string key)
{
    return data.GetOrAdd(key, async (x) => {
        return await LoadAsync(x);
    });
}

static async Task<string[]> LoadAsync(string key) {....}

但这给了我错误:

无法将异步 lambda 表达式转换为委托类型“System.Func”。

异步 lambda 表达式可能返回 void、Task 或 Task,其中任何一个都不能转换为“System.Func”。

据我了解,这是因为GetOrAdd()不是异步的。我该如何解决这个问题?

Update: LazyAsync评论中建议的将在我的小例子中起作用。或者,像这样的解决方法(绝对可以忍受它引入的一些开销):

public static async Task<string[]> GetStuffAsync(string key)
{
    string[] d = null;
    if (!data.ContainsKey(key))
        d = await LoadAsync(key);
    return data.GetOrAdd(key, d);
}

那么问题就变成了微软是否没有时间更新所有接口来支持异步,或者我正在尝试做一些严重错误的事情(并且ConcurrentDictionary不应该有GetOrAddAsync()) ?


异步方法(或 lambda)只能返回void or Task or Task<T>但你的 lambda 返回string[]因此编译器会阻止你。

await关键字经过优化,可以在任务已完成时同步继续。因此,一种选择是将任务本身存储在字典中,而不必担心一次又一次等待完成的任务。

private static ConcurrentDictionary<string, Task<string[]>> data =
    new ConcurrentDictionary<string, Task<string[]>>();

public static Task<string[]> GetStuffAsync(string key)
{
    return data.GetOrAdd(key, LoadAsync);
}

当你这样做时

var item = await GetStuffAsync(...);

第一次它会(a)等待直到缓存的任务完成——之后它将同步继续。

你必须考虑什么时候会发生什么LoadAsync失败了。因为我们正在缓存返回的任务LoadAsync;如果失败,我们将愚蠢地缓存失败的任务。您可能需要处理这个问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

同步函数内的异步调用 的相关文章

随机推荐

  • 如何破译 boost asio ssl 错误代码?

    我在 boost asio ssl 实现中偶尔会出现通信失败 boost 返回的超级有用的错误消息是 asio ssl 336458004 我怀疑数字是由 SSL 标志组成的某种聚合构造 我说因为 linux 错误代码 boost asio
  • 从 FileSystemWatcher 错误中恢复的最佳实践是什么?

    After a FileSystemWatcher Error事件被提出 我不知道下一步该做什么 该例外可以是 相对 较小的例外 例如 目录中一次更改太多 这不会影响观察者的观看过程 但它也可能是一个大问题 例如观看的目录被删除 在这种情况
  • 如何以编程方式设置可发现时间而无需用户确认?

    我通常用这个 private void ensureDiscoverable if D Log d TAG ensure discoverable if mBluetoothAdapter getScanMode BluetoothAdap
  • 不使用 Android 导航抽屉显示叠加层

    我想知道是否可以删除最近实现的导航抽屉所做的自动覆盖 第二张图的灰色层 你只需要设置setScrimColor int color 给你的DrawerLayout mDrawerLayout setScrimColor Color WHIT
  • postgresql:共享内存不足?

    我正在使用 Python 和 psycopg2 运行大量查询 我创建了一个包含约 200 万行的大型临时表 然后使用以下命令一次从中获取 1000 行cur fetchmany 1000 并运行涉及这些行的更广泛的查询 不过 广泛的查询是自
  • 如何使用 StoreKit 2 进行恢复?

    iOS 15 引入了 StoreKit 2 我正在研究它 看看是否可以在我现有的应用程序中采用它 但我不知道该怎么做 特别是 我不知道如何实现所需的恢复功能 例如 如果用户删除了我的应用程序 我想我们应该使用Transaction late
  • 当我向 Firebase 实时数据库添加新值时如何保存当前日期/时间

    当我通过控制面板向 Firebase 实时数据库添加新值时 我想将当前日期 时间保存在特定字段中 我怎样才能做到这一点 请帮我 Answer recommended by Google Cloud Collective 最佳实践是将数据保存
  • JSP/JSTL 中的嵌套表达式

    我使用 JSP 作为视图 使用 Spring MVC 3 0 作为控制器 在我的 JSP 中 我想显示当前的日期时间 为此我有以下代码
  • Linux 内核模块字符设备权限

    是否可以在以 mod 666 启动的 Linux 内核模块中创建字符设备 现在它总是 600 由 root 拥有 我必须 chmod 它 我可以创建 udev 条目来解决它 但我真的宁愿模块自动执行它 是否可以 我在 cdev init 或
  • 异步/等待返回 Promise { } [重复]

    这个问题在这里已经有答案了 我的问题是 尽管我使用了 async await 为什么这个日志还是 promise pending 我检查了类似的问题和答案 看起来应该没问题 但事实并非如此 我该如何改变它才能得到结果 为什么 谢谢 cons
  • 带有 CloudFront 的区域 API 网关

    亚马逊发布新功能 支持区域 API 端点 这是否意味着我可以在两个区域部署相同的 API 代码 并向 Lambda 微服务发送请求 这将是两个不同的 Https 端点 CloudFront 是否为我分配流量 有代码片段吗 这是否意味着我可以
  • DART HTTP 服务器中带有 SSL 证书的 HTTPS

    Dart HTTP 服务器支持 HTTPS 吗 如果是这样 您如何指定证书 如果没有 是否有其他替代方案 例如社区创建的包 是的 Dart 支持 https 查看文档here和一个测试here 相关线路 HttpServer bindSec
  • 为图层属性设置动画以简单地更改其他属性?

    想象一个CAGradientLayer 制作动画非常容易 startPoint and endPoint 现在想象一个漂浮物spinLike这只是同时设置它们 因此 您可以简单地制作动画 而不是使用两个不同的动画spinLike 所以像 c
  • 如何忽略地图框图层上的鼠标事件

    我在 Mapbox 地图上构建了一个标记 当用户将鼠标悬停在其上时 该标记如下所示 我遇到的问题是文档图标是与背景图钉不同的层 这样用户就可以上传自定义图标 当使用mouseover and mouseleave事件在背景图钉层上创建悬停弹
  • 按属性名称(字符串值)排序列表? [复制]

    这个问题在这里已经有答案了 我有一个清单objects 如何使用属性名称订购此列表 string orderbyField Code List l FillList l l OrderBy o gt orderbyField 我可以为这个问
  • GeoDjango:我可以在用户管理中内联使用 OSMGeoAdmin 吗?

    Profile包含一个PointField 我在 ProfileAdmin 中使用了 OSMGeoAdmin 如下 class ProfileAdmin admin OSMGeoAdmin model Profile 但无法弄清楚如何在内联
  • 如何在浏览器控制台中访问 *angular 2* 组件的数据?

    我有一个 DisplayComponent 我想在浏览器 开发人员的控制台中查看它的数据 我怎样才能看到它 示例来自Angular2 分步指南 function DisplayComponent this myName Alice 我怎么看
  • 使用 spring-mvc 将异常序列化为 JSON

    RequestMapping ResponseBody public SearchResponse search SearchRequest request throws SearchException 我想回复请求者 JSON 序列化搜索
  • 使用 PHP 防止表中出现重复记录 [重复]

    这个问题在这里已经有答案了 我想防止使用 PHP 的表单中的重复值进入数据库表 我创建了以下内容 具有名为的表的数据库clients CREATE TABLE clients firstName varchar 20 lastName va
  • 同步函数内的异步调用

    我正在尝试异步填充我的缓存 static ConcurrentDictionary