尝试同步调用 Async 方法。它永远等待 Task.Result [重复]

2024-01-06

因此,我正在编写一个应用程序,我想在其中公开一系列具有同步和异步等效方法的方法。为此,我认为最简单的方法是在 asnyc 方法中编写逻辑,并编写同步方法作为异步方法的包装器,同步等待它们传递结果。代码没有发挥作用。在下面的代码示例中(不是我的真实代码,而是基本问题的简化),该行Console.WriteLine(result)永远不会到达 - 前一行永远挂起。但奇怪的是,如果我或多或少地将这个模式逐字复制到控制台应用程序中,它就会起作用。

我究竟做错了什么?这只是一个糟糕的模式吗?如果是这样,我应该使用什么模式?

public partial class MainWindow : Window {

    public MainWindow() {
        this.InitializeComponent();
        var result = MyMethod(); //Never returns
        Console.WriteLine(result);
    }

    public string MyMethod() {
        return MyMethodAsync().Result; //Hangs here
    }

    public async Task<string> MyMethodAsync() { //Imagine the logic here is more complex
        using (var cl = new HttpClient()) {
            return await cl.GetStringAsync("http://www.google.co.uk/");
        }
    }

}

这是一个经典的僵局。 UI 正在等待异步方法完成,但异步方法尝试更新 UI 线程并轰隆隆,陷入僵局。

但奇怪的是,如果我将这个模式或多或少地逐字复制到 控制台应用程序,它可以工作。

那是因为你的 WinForm 应用程序有一个自定义的SynchronizationContext。它是隐式捕获的,它的工作是在从您的应用程序返回后将工作编组回 UI 线程。await.

您真的应该公开异步操作的同步包装器吗? http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx, 答案是no.

有一个解决办法,但我不太喜欢它。如果你绝对have to(你不)同步调用你的代码(同样,你真的不应该),使用ConfigureAwait(false)在异步方法内部。这指示awaitable不捕获当前的同步上下文,因此它不会将工作重新编组到 UI 线程上:

public async Task<string> MyMethodAsync() 
{ 
    using (var cl = new HttpClient()) 
    {
        return await cl.GetStringAsync("http://www.google.co.uk/")
                       .ConfigureAwait(false);
    }
}

请注意,如果您执行此操作,然后尝试调用任何 UI 元素,您最终会得到一个InvalidOperationException因为你不会在 UI 线程上。

通过构造函数初始化 UI 是一种常见模式。 Stephan Cleary 有一个非常好的关于异步的系列,你可以找到here http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html.

我究竟做错了什么?这是否只是一个糟糕的模式?如果是,那么是什么? 我应该使用模式吗?

是的,一点没错。如果您想公开异步和同步 API,请使用正确的 api,这不会让您在第一种情况下陷入这种情况(死锁)。例如,如果您想公开一个同步DownloadString, use WebClient http://msdn.microsoft.com/en-us/library/system.net.webclient(v=vs.110).aspx反而。

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

尝试同步调用 Async 方法。它永远等待 Task.Result [重复] 的相关文章

随机推荐

  • 从 python 内部调用 python 脚本

    我花了很长时间才找到这个解决方案 所以我希望其他人能够看到它 我想编写一个 python 脚本来创建一个虚拟环境并在其中安装模块 不幸的是 pip 不能很好地与子进程配合 详细信息如下 https github com pypa pip i
  • 如何使用 HTML AGILITY PACK 调用 Click

    In 网页浏览器 网络表格 我们可以InvokeMember click 当我们解析 HTML 时 我们怎样才能做到这一点HTML 敏捷包 a href 当我们在 Href 中有 javascript 时 如何使用 HTTP REQUEST
  • 绘图完全无边框

    我在 png 图像文件上设置了一个带有透明叠加散点图的漂亮图 我希望我的绘图窗口和 pdf 输出的大小与我的 png 962x745 完全相同 然而 即使在关闭轴 注释和框架之后 R 仍然在图像周围留下边框 这可以通过一个简单的示例来显示
  • SwiperJS - 如何设计分页项目符号的样式?

    在我的 ReactJS 应用程序中使用 SwiperJS 我已导入默认样式包 但无法弄清楚如何设置分页容器或项目符号的样式 In the pagination 参数在 内 每次我改变el param 分页就消失了 每次我改变bulletCl
  • 在 RecyclerView 中回收时,项目视图无法正确测量

    我有一个场景 当视图被回收时 布局不正确 我的行项目布局如下 注意wrap content线性布局宽度 weight and ellipsize
  • GSON - 特定情况下的自定义序列化器

    我有这个架构 public class Student public String name public School school public class School public int id public String name
  • 从提供者读取数据时发生错误。根据验证程序,远程证书无效

    I m trying to connect Postgres Database on AWS EC2 instance to Microsoft PowerBI I tried various method available on int
  • 如何找出访问者的 RAM 和 GPU 信息?

    我想知道我的访问者有多少 RAM 以及有关他们的 GPU 的所有可用信息 有没有办法通过 JavaScript 或者 ActionScript Flash 来实现这一点 Use navigator deviceMemory 查找设备 RAM
  • 如何使 y 轴上的数字显示以百万为单位的值,而不是 matplotlib 中的科学记数法?

    如何更改 y 轴上的数字以显示 0 到 1700 万而不是 0 到 1 75 1e7 import numpy as np import pandas as pd import matplotlib pyplot as plt import
  • 在设备上运行phonegap - 未找到设备

    我正在尝试在我的设备上运行一个在phonegap中制作的应用程序 并通过USB连接 gt phonegap run android phonegap detecting Android SDK environment phonegap us
  • 忽略属性覆盖

    Content of Build xml File
  • 在 IE 上自动打开文件输入

    IE输入的文件可以自动打开吗 如果你这样做 input click IE 不提交表单 也许我能以某种方式获得它的价值 input val 不起作用 这会给你假路径 对此有什么想法吗 克隆也不起作用 另一种可能性是将打开按钮放置在页面上的其他
  • 如何创建卡车/卡车后视镜的形状?

    circle width 40px height 40px border radius 50 background color yellow position absolute z index 20 border 1px solid AAA
  • VSCode HTML 缩进,同一行的结束标记

    在 HTML 文件上使用 VSCode 缩进时 右括号结束于下一行 我该如何解决这个问题 我搜索了 HTML 缩进扩展 但没有成功 总氮 转到 设置 gt 搜索自动换行 editor wordWrap off 愿它对你有帮助
  • MATLAB:比较三个数组中的所有元素

    我有三个一维数组 其中元素是一些值 我想将一个数组中的每个元素与其他两个数组中的所有元素进行比较 例如 a 2 4 6 8 12 b 1 3 5 9 10 c 3 5 8 11 15 我想知道不同数组中是否有相同的值 在本例中有 3 5 8
  • Crashlytics 不适用于 Xcode 10 beta

    我使用 Firestore 和 Google 提供的一些子服务 Crashlytics 就是其中之一 我最近开始使用 Xcode 10 beta 并且开始收到此错误 Users
  • Python 剥离方法

    今天在 python 终端中 我尝试了 a serviceCheck postmaster a strip serviceCheck 但不是得到 postmaster 我有 postmast 什么可能导致这种情况 我怎样才能得到 postm
  • 类型 Any 没有下标成员 json Swift 3

    我有这个代码 let subjectAbbreviation JSON data subject abbr as String Swift 3 抱怨 Any 类型没有下标成员 我该如何解开这个 我知道我可以使用 JSON as AnyObj
  • 如何关闭多个彼此独立的div。 javascript

    我构建了一排 4 个按钮来打开 4 个 div 一次打开一个 用户可以通过单击这些按钮在 4 个 div 之间切换 但是 用户必须能够再次关闭该 div 并且彼此独立 这意味着如果用户单击这些按钮之一 他必须能够仅使用一个 关闭按钮 再次关
  • 尝试同步调用 Async 方法。它永远等待 Task.Result [重复]

    这个问题在这里已经有答案了 因此 我正在编写一个应用程序 我想在其中公开一系列具有同步和异步等效方法的方法 为此 我认为最简单的方法是在 asnyc 方法中编写逻辑 并编写同步方法作为异步方法的包装器 同步等待它们传递结果 代码没有发挥作用