如何将await/async 与同步代码结合使用?

2024-02-25

我正在尝试使用await/async 来使一些同步代码异步。例如,这可以工作并解除 UI 线程的阻塞:

private async void button1_Click(object sender, EventArgs e)
{
    var task = DoRequestAsync();
    textBox1.Text = "starting async task";
    var text = await task;
    textBox1.Text = text;
}

private async Task<string> DoRequestAsync()
{
    try
    {
        var client = new HttpClient();
        client.Timeout = new TimeSpan(0, 0, 0, 5);
        await client.GetAsync("http://123.123.123.123"); // force a timeout exception
    }
    catch (Exception e)
    {
    }

    return "done!";
}

但这不会,并且会挂起 UI 线程:

private async void button1_Click(object sender, EventArgs e)
{
    var task = DoRequestAsync();
    textBox1.Text = "starting async task";
    var text = await task;
    textBox1.Text = text;
}

private async Task<string> DoRequestAsync()
{
    try
    {
        var request = WebRequest.Create("http://123.123.123.123");
        request.Timeout = 5000;
        request.GetResponse(); // force a timeout exception
    }
    catch (Exception e)
    {
    }

    return "done!";
}

我试图理解为什么会出现这种情况。我的印象是var task = DoRequestAsync()将创建一个新线程并异步运行该方法中的所有内容,但情况似乎并非如此。

我可以用它来使它工作:

await Task.Run(() => {
    var request = WebRequest.Create("http://123.123.123.123");
    request.Timeout = 5000;
    request.GetResponse();
});

但这似乎有点老套,我不确定这是否是解决这个问题的正确方法。有谁知道我如何使用任务和异步/等待以异步方式运行一堆同步代码?


这是正确的解决方案。WebRequest.GetResponse不是异步方法,因此它不返回任务。它不能异步运行。

实际上,您所拥有的是您可以获得的最正确和速记的解决方案(使用Task.Run).

我的印象是 var task = DoRequestAsync() 会 创建一个新线程并异步运行方法中的所有内容, 但事实似乎并非如此。

这不是魔法。为了使其异步运行,必须在异步方法中创建一个新任务(不是线程),或者它必须等待一个或多个返回任一方法的方法)Task, Task<T> or void(这是针对事件处理程序的)。

方法中的最后一条语句return "done!";只返回一个已完成的Task<string>结果“完成”。

附带说明一下,这就是 HttpClient 成为事实上的 HTTP 请求类的原因,特别是对于与 Web API 互操作,但也用于通用 GET/POST/等:它有异步支持.

任务还支持包装 Begin*/End* 函数(符合前面的异步编程模型——APM http://msdn.microsoft.com/en-us/library/ms228963(v=vs.110).aspx)。您还可以这样做:

try
{
    var request = WebRequest.Create("http://123.123.123.123");
    request.Timeout = 5000;
    await Task.Factory.FromAsync(request.BeginGetResponse(), request.EndGetResponse, null); // force a timeout exception
}
catch (Exception e)
{
    //TODO handle exception here
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将await/async 与同步代码结合使用? 的相关文章

  • 创建 DirectoryEntry 实例以供测试使用

    我正在尝试创建 DirectoryEntry 的实例 以便可以使用它来测试将传递 DirectoryEntry 的一些代码 然而 尽管进行了很多尝试 我还是找不到实例化 DE 并初始化它的 PropertyCollection 的方法 我有
  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • 如何在 Unity 中从 RenderTexture 访问原始数据

    问题的简短版本 我正在尝试访问 Unity 中 RenderTexture 的内容 我一直在使用 Graphics Blit 使用自己的材质进行绘制 Graphics Blit null renderTexture material 我的材
  • Cygwin 下使用 CMake 编译库

    我一直在尝试使用 CMake 来编译 TinyXML 作为一种迷你项目 尝试学习 CMake 作为补充 我试图将其编译成动态库并自行安装 以便它可以工作 到目前为止 我已经设法编译和安装它 但它编译成 dll 和 dll a 让它工作的唯一
  • C# 中可空类型是什么?

    当我们必须使用nullable输入 C net 任何人都可以举例说明 可空类型 何时使用可空类型 https web archive org web http broadcast oreilly com 2010 11 understand
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • Windows 窗体不会在调试模式下显示

    我最近升级到 VS 2012 我有一组在 VS 2010 中编码的 UI 测试 我试图在 VS 2012 中启动它们 我有一个 Windows 窗体 在开始时显示使用 AssemblyInitialize 属性运行测试 我使用此表单允许用户
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反

随机推荐

  • 源代码管理中的 .vcxproj

    我一直在阅读很多关于 vcxproj 文件是否应该添加到源代码管理中的问题 共识似乎是他们应该这样做 但是当打开文件时 我注意到其中包含很多用户特定的路径 鉴于这是一个由很多人共同开发的项目 我还应该将其添加到源代码管理中吗 看起来它会与其
  • Json.NET - CustomCreationConverter 中单个属性的默认反序列化行为

    在下面的场景中 我如何得到CrazyItemConverter当遇到我要反序列化的类型中存在的 JSON 属性时 是否照常进行 我有一些如下所示的 JSON Item Name Apple Id null Size 5 Quality 2
  • Symfony sfDoctrineGuardPlugin 自定义登录查询

    我使用 symfony sfDoctrineGuardPlugin 来管理前端用户和后端用户的身份验证 没关系 只是我不希望前端用户能够登录后端应用程序 我可以设置凭据 但在用户通过身份验证后会检查凭据 我想要的是以表单形式登录 永远不会验
  • 使第二个弹性列可滚动

    我看到这个例子来自Flex flex column 内的可滚动 div https stackoverflow com questions 34157058 flex scrollable div inside flex column并尝试
  • 安装 Vuetify 后需要额外的加载器

    使用最新的 VueCli 构建的干净项目 使用 vue add vuetify 添加了 Vuetify 一切正常 添加了身份验证脚本 我今年已经成功使用了 3 次 现在我收到此错误 ERROR Failed to compile with
  • Visual Studio 2015 - 用户任务消失了?

    我最近从 Visual Studio 2013 切换到 2015 并转换了所有旧项目 但是 现在我似乎找不到我的用户任务了 任务列表中曾经有一个下拉菜单 但看起来在新版本中已经消失了 除非我遗漏了一些东西 用户任务是否被删除 如果是这样 我
  • Web3.py:使用待处理过滤器时出现 ValueError

    我正在尝试使用 web3 py 查找 BEP20 网络中的待处理交易 如中所述在这个堆栈溢出问题中 https stackoverflow com questions 57201888 different ways of getting e
  • 使用泛型和协议作为类型参数之间的区别,在函数中实现它们的优缺点是什么

    由于 Swift 允许我们在函数中使用 Protocol 和 Generic 作为参数类型 所以我想到了下面的场景 protocol AProtocol var name String get class ClassA AProtocol
  • 检查php中是否存在session

    在我的 php 函数中 我想检查会话是否存在 根据会话的存在 我想返回 true 或 false 我有一个登录功能 它使用session start 并在登录时将值存储到会话变量中 并且在注销时将执行此操作session destroy 现
  • list.extend 和列表理解[重复]

    这个问题在这里已经有答案了 当我需要向列表中添加几个相同的项目时 我使用 list extend a a b c a extend d 3 Result a b c d d d 但是 如何与列表理解进行类似的操作呢 a a 2 b 2 c
  • CSS @page 中的不同大小:第一个结果整个@page 大小相同

    它与打印有关 并且仅与打印有关 css page size A4 portrait page first size 210mm 1000mm 根据 CSS 的定义 只有首页高度为 1000 毫米 其余页面高度为 297 毫米 A4 但在 C
  • 为什么在 JavaScript 中返回时要使用括号?

    在Restify框架代码中我发现了这个函数 function queryParser options function parseQueryString req res next Some code goes there return ne
  • 获取逗号分隔字符串的第一个值[重复]

    这个问题在这里已经有答案了 我正在寻找从逗号分隔的字符串中获取第一个值的最快 最短的方法 in line 我能做的就是 string a b c d echo The first thing is end array reverse exp
  • 在 Cypher 查询中使用正则表达式捕获组

    在密码中文档 http docs neo4j org chunked milestone query where html regular expressions它说您可以使用正则表达式来匹配字符串属性中的特定 先前已知 模式 是否也可以使
  • WPF 着色器效果 - 抗锯齿不显示

    我遇到一个问题 我有一个 WPF 着色器效果 由 Rene Schulte 修改 来模拟点阵显示 DMD 一切都很好 但所有的点都是别名的 See attached image 我尝试了WPF中的许多功能 以带来抗锯齿 但无济于事 在构造函
  • 按退出键退出循环

    我试图通过按转义键退出循环 但我的程序不起作用 有没有办法做到这一点 我的代码 import win32api import win32con import time from msvcrt import kbhit getch def c
  • 使用 Java 代码向 main_activity 视图添加按钮

    我想添加一个Button to the main activity使用java代码查看 那么我该怎么做呢 我已经尝试过这段代码 不幸的是它不起作用 public class MainActivity extends Activity But
  • mave 3.2 无法访问本地 Nexus 实例返回 502 代码

    访问本地主机中的本地 Nexus 存储库时 返回代码为 502 pom xml 看起来像这样
  • 在 Windows 10 上为 GitHub 启用多个 SSH 密钥

    我有 2 个 GitHub 帐户 我无法为这两个帐户使用相同的公钥 我已经生成了2个ssh密钥 C Users User Name ssh id rsa C Users User Name ssh id rsa another 我的问题是
  • 如何将await/async 与同步代码结合使用?

    我正在尝试使用await async 来使一些同步代码异步 例如 这可以工作并解除 UI 线程的阻塞 private async void button1 Click object sender EventArgs e var task D