想了解异步

2023-11-24

我使用过一点异步编码,但我并没有真正完全理解如何使用它——尽管我理解这个概念以及为什么我需要它。

这是我的设置:

我有一个 Web API,我将从 ASP.NET MVC 应用程序调用它,而我的 Web API 将调用 DocumentDB。在代码示例中,我在向 DocumentDB 发送查询时看到很多 wait 关键字。

我很困惑是否需要在 MVC 应用程序中使索引操作方法异步? 我也很困惑我的 Web API 中的 CreateEmployee() 方法是否应该是异步的?

在这种情况下使用异步的正确方法是什么?

这是我的代码(此代码当前给我错误,因为我的 MVC 操作方法不是异步的) ---- ASP.NET MVC 应用程序代码 ----

public ActionResult Index()
{

   Employee emp = new Employee();
   emp.FirstName = "John";
   emp.LastName = "Doe";
   emp.Gender = "M";
   emp.Ssn = "123-45-6789";

   using (var client = new HttpClient())
   {
      client.BaseAddress = new Uri("http://myWebApi.com");
      client.DefaultRequestHeaders.Accept.Clear();
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

      HttpResponseMessage response = await client.PostAsJsonAsync("hr/create/newemployee", emp);
      if (response.IsSuccessStatusCode)
      {
         emp = await response.Content.ReadAsAsync<Employee>();
      }
   }

   // Display employee info
   return View(emp);
}

---- Web API 代码 ----

private static readonly string endPointUrl = ConfigurationManager.AppSettings["EndPointUrl"];
private static readonly string authorizationKey = ConfigurationManager.AppSettings["AuthorizationKey"];
private static readonly string databaseId = ConfigurationManager.AppSettings["DatabaseId"];
private static DocumentClient client;

public static async Task<Employee> CreateEmployee(Employee emp)
{
   try
   {
      //Create a Document client
      using (client = new DocumentClient(new Uri(endPointUrl), authorizationKey))
      {
         //Get the database
         var database = await GetDatabaseAsync();

         //Get the Document Collection
         var collection = await GetCollectionAsync(database.SelfLink, "Employees");

         await client.CreateDocumentAsync(collection.SelfLink, emp);

         // Further process employee
       }
    }
    catch
    {
       // Handle error
    }

    return employee;
}

private static async Task<DocumentCollection> GetCollectionAsync(string dbLink, string id)
{
   DocumentCollection collection = client.CreateDocumentCollectionQuery(dbLink).Where(c => c.Id == id).ToArray().FirstOrDefault();

   return collection;
}

private static async Task<Database> GetDatabaseAsync()
{
   Database database = client.CreateDatabaseQuery().Where(db => db.Id == databaseId).ToArray().FirstOrDefault();

   return database;
}

这是我的解释

class MainClass
{
    public static async Task<String> AsyncMethod(int delay) {

        await Task.Delay (TimeSpan.FromSeconds(delay));

        return "The method has finished it's execution after waiting for " + delay + " seconds";
    }

    public static async Task Approach1(int delay)
    {
        var response = await AsyncMethod (delay); // await just unwraps Task's result

        Console.WriteLine (response);
    }

    public static Task Approach2(int delay)
    {
        return AsyncMethod(delay).ContinueWith(message => Console.WriteLine(message)); // you could do the same with 
    }

    public static void Main (string[] args)
    {
        var operation1 = Approach1 (3);
        var operation2 = Approach2 (5);

        Task.WaitAll (operation1, operation2);

        Console.WriteLine("All operations are completed")
    }
}

最终两者Approach1 and Approach2是相同的代码片段。

The async/await是围绕任务 API 的语法糖。这需要你的async方法之前将其分成几部分await, 之后await。 “之前”部分立即执行。 “之后”部分在以下情况下执行await操作完成。由于您获得了对任务的引用,因此您可以通过任务 API 跟踪操作的第二部分。

一般来说async允许将方法调用视为某种长操作,您可以通过任务 API 引用该操作,并等待它完成并继续执行另一段代码。要么通过ContinueWith通过使用调用await一般来说是一样的。

Before async/await/Task人们使用回调的概念,但处理错误非常简单,Task类似于一个概念callback除了它能够更轻松地处理异常之外。

一般来说,所有这些任务/异步/等待口头禅都接近概念promises如果您碰巧使用过 jQuery/JavaScript,那么这里有一个类似的概念,这是一个很好的问题,解释了它是如何完成的“jQuery 延迟和承诺 - .then() 与 .done()"


Edit:我刚刚发现 .NET 缺少以下实现then功能类似于 jQuery/JavaScript 中的功能。

和...之间的不同ContinueWith and Then就是它Then能够组合任务并按顺序执行它们ContinueWith不是,它只能并行启动任务,但可以通过await 结构轻松实现。这是我更新的代码,包含整个 shebang:

static class Extensions
{
    // Implementation to jQuery-like `then` function in .NET
    // According to: http://blogs.msdn.com/b/pfxteam/archive/2012/08/15/implementing-then-with-await.aspx
    // Further reading: http://blogs.msdn.com/b/pfxteam/archive/2010/11/21/10094564.aspx
    public static async Task Then(this Task task, Func<Task> continuation) 
    { 
        await task; 
        await continuation(); 
    } 

    public static async Task<TNewResult> Then<TNewResult>( 
        this Task task, Func<Task<TNewResult>> continuation) 
    { 
        await task; 
        return await continuation(); 
    } 

    public static async Task Then<TResult>( 
        this Task<TResult> task, Func<TResult,Task> continuation) 
    { 
        await continuation(await task); 
    } 

    public static async Task<TNewResult> Then<TResult, TNewResult>( 
        this Task<TResult> task, Func<TResult, Task<TNewResult>> continuation) 
    { 
        return await continuation(await task); 
    }
}

class MainClass
{
    public static async Task<String> AsyncMethod1(int delay) {

        await Task.Delay (TimeSpan.FromSeconds(delay));

        return "The method has finished it's execution after waiting for " + delay + " seconds";
    }

    public static Task<String> AsyncMethod2(int delay)
    {
        return Task.Delay (TimeSpan.FromSeconds (delay)).ContinueWith ((x) => "The method has finished it's execution after waiting for " + delay + " seconds");
    }

    public static async Task<String> Approach1(int delay)
    {
        var response = await AsyncMethod1 (delay); // await just unwraps Task's result

        return "Here is the result of AsyncMethod1 operation: '" + response + "'";
    }

    public static Task<String> Approach2(int delay)
    {
        return AsyncMethod2(delay).ContinueWith(message => "Here is the result of AsyncMethod2 operation: '" + message.Result + "'");
    }

    public static void Main (string[] args)
    {
        // You have long running operations that doesn't block current thread
        var operation1 = Approach1 (3); // So as soon as the code hits "await" the method will exit and you will have a "operation1" assigned with a task that finishes as soon as delay is finished
        var operation2 = Approach2 (5); // The same way you initiate the second long-running operation. The method also returns as soon as it hits "await"

        // You can create chains of operations:
        var operation3 = operation1.ContinueWith(operation1Task=>Console.WriteLine("Operation 3 has received the following input from operation 1: '" + operation1Task.Result + "'"));
        var operation4 = operation2.ContinueWith(operation2Task=>Console.WriteLine("Operation 4 has received the following input from operation 2: '" + operation2Task.Result + "'"));

        var operation5 = Task.WhenAll (operation3, operation4)
            .Then(()=>Task.Delay (TimeSpan.FromSeconds (7)))
            .ContinueWith((task)=>Console.WriteLine("After operation3 and 4 have finished, I've waited for additional seven seconds, then retuned this message"));

        Task.WaitAll (operation1, operation2); // This call will block current thread;

        operation3.Wait (); // This call will block current thread;
        operation4.Wait (); // This call will block current thread;
        operation5.Wait (); // This call will block current thread;

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

想了解异步 的相关文章

  • 成员字段、构建顺序

    在 C 中 当执行如下所示的操作时 构造顺序是否得到保证 Logger Logger kFilePath logs runtime log logFile kFilePath 是的 施工顺序始终得到保证 但是 不能保证它与对象在初始值设定项
  • 显示 div 内的用户名列表

    我是 jQuery 新手 在我的项目中 我创建了一个类User其中代码如下所示 static ConcurrentDictionary
  • 读取大文件并制作字典

    我有一个大文件 我需要读取它并从中制作字典 我希望这一切能够尽可能快 然而我的Python代码太慢了 这是一个显示问题的最小示例 首先制作一些假数据 paste lt seq 20000000 lt seq 2 20000001 gt la
  • 如何使用最小起订量模拟私有只读 IList 属性

    我试图嘲笑这个列表 private readonly IList
  • 无需登录即可在 Intranet 上获取 Web 应用程序的域\用户名

    我的 Intranet 上有一个 Web 应用程序 VS 2005 有几个页面不需要用户登录应用程序 反馈和默认页面 我正在尝试获取要显示和 或发送反馈的域名和用户名 有没有一种方法可以在不需要用户登录的情况下执行此操作 我试过了this
  • C++0x 初始值设定项列表示例

    我想看看这个现有代码示例如何利用 C 0x 初始化列表功能 示例0 include
  • 如何部署包含第三方 DLL 文件的 C# 应用程序?

    首先 我对部署了解不多 我希望我的问题有意义 我需要将 C 应用程序安装 部署到多个桌面 它需要一个第三方 DLL 文件 一个 C 库 lpsolve55 dll 对于那些感兴趣的人 它是一个免费的 MIP LP 求解器 请参阅 lpsol
  • 如何将 Visual-Studio 2010 切换到 c++11

    我是 c 编程新手 我想尝试 c 11 新功能 那么我要问的是如何切换 Visual studio 2010 才能编译 c 11 源代码 你可以参考这个表 VC10 中的 C 0x 核心语言功能 表格 http blogs msdn com
  • PartialView Action 正在调用自身

    我有 MVC 应用程序 它用于从主视图 ProductMaster 将 ProductAreaGrid 列表显示为 PartialView 并且它将在局部视图内将 CreateProductArea 作为 PartialView 我的 Gr
  • += 运算符在 C++ 中是如何实现的?

    这是我一直在思考的一个问题 但从未找到任何资源来说明这个问题的答案 事实上它不仅是为了 也适用于它的兄弟姐妹 即 等等 当然不是 考虑这个例子 int a 5 a 4 this will make a 9 现在考虑等效表达式 a a 4 T
  • 主构造函数不再在 VS2015 中编译

    直到今天 我可以使用主构造函数 例如 public class Test string text private string mText text 为了能够做到这一点 在以前的 Visual Studio CTP 中 我必须将其添加到 c
  • Web 文本编辑器中的 RTF 格式

    网络上是否有支持 RTF 格式文档输入的文本编辑器 我知道这对 webdev 来说有点奇怪 但我需要从数据库中读取 RTF 文档 并在基于 Web 的文本编辑器中对其进行编辑 然后将其存储回 RTF 中 在我在转换工具上投入太多资金之前 我
  • C# 反序列化过程中创建指向父对象的指针

    我有这样的课程 Serializable public class child public Parent parent Serializable public class Parent public List
  • 确定相关词的编程方式?

    使用网络服务或软件库 我希望能够识别与词根相关的单词 例如 座位 和 安全带 共享词根 座位 但 西雅图 不会被视为匹配 简单的字符串比较对于这类事情似乎是不可行的 除了定义我自己的字典之外 是否有任何库或 Web 服务不仅可以返回单词定义
  • 文件加密与解密问题

    我一直在尝试在 VC Express 2010 中加密和解密文件 我见过的所有教程和文档都需要两个FileStreams 来加密文件 一个用于读取未加密的版本 另一个用于加密 当我实际编写代码时 它不断抛出错误 告诉我它无法打开该文件 因为
  • 如何解决文件被另一个进程使用的问题?

    我一直在 VS NET 2010 中调试 没有任何问题 但现在无法建造 我收到错误 Unable to copy file filename to bin Debug filename The process cannot access t
  • 文本框中“结束编辑”的事件

    我正在 winform c 中使用文本框 并使用文本在数据库中进行查询 但每次文本更改时 我都需要不断查阅文本框的文本 因此 对于这些 我使用 KeyUp 但这个活动太慢了 文本框编辑完成后是否会触发任何事件 我考虑完成2个条件 控制失去焦
  • 如何使 WinForms UserControl 填充其容器的大小

    我正在尝试创建一个多布局主屏幕应用程序 我在顶部有一些按钮链接到应用程序的主要部分 例如模型中每个实体的管理窗口 单击这些按钮中的任何一个都会在面板中显示关联的用户控件 面板包含用户控件 而用户控件又包含用户界面 WinForms User
  • Web API 2.0 使用 pascalcase 模型接收驼峰式命名的 JSON 数据

    我正在尝试对我的 Web API 进行 PUT 调用 我在 WebApiConfig cs 中设置了以下内容 以处理以驼峰形式将数据发送回我的 Web 项目 config Formatters JsonFormatter Serialize
  • 在两个点之间创建一条曲线,每个点都具有标准化向量

    因此 我需要一种写入方法来在两点之间创建一条曲线 每个点都有一个指向任意方向的归一化向量 我一直在尝试设计这样一种方法 但一直无法理解数学 在这里 由于一张图片胜过一千个文字 这就是我所需要的 在图中 矢量垂直于红线 我相信向量需要进行相同

随机推荐

  • 使用 POEdit——仅搜索特定域中的字符串

    我创建了一个想要翻译的 WordPress 主题 在我的主题中 我使用了一些翻译woocommerce i e 这些 woocommerce 字符串 我自然不想再次翻译 因为它们已经被翻译了 但是当我使用 poedit 扫描我的主题时 它当
  • java.sql.SQLException:I/O 错误:SSO 失败:本机 SSPI 库

    我有两个网络应用程序需要在 Tomcat 6 MS SQL 2008 和 JTDS 1 2 2 作为驱动程序上运行 如果我只启动一个 Web 应用程序 一切都工作正常 但是一旦我启动第二个应用程序 我就会收到以下错误 顺序无关紧要 java
  • 获得Facebook的读取权限后获得publish_action权限

    我正在整合Facebook登录我的应用程序 我能够获得读取权限 但如何从 Facebook SDK 获得发布权限 这就是我请求读取权限的方式 Override public void onClick View v Session curre
  • 如何让 addEventListener 与 select 标签一起使用

    HTML
  • event.preventDefault() 不适用于 android chrome

    event preventDefault 不适用于 Chrome Android 操作系统 而同样的操作也适用于 chrome IOS 我什至使用了 event stopPropagation event stopImmediateProp
  • Spring-Boot 多模块无法从另一个模块读取属性文件

    我搜索了高低 但仍然无法找到这个非常烦人的问题的简单答案 我遵循了这个伟大的指南 JWT 与多服务应用程序一切都很好 但在指南的最后 建议我们创建一个 config service module 我已经完成了 问题是我无法覆盖 JwtCon
  • 在 ICS 或 JB 上的任务管理器中显示自定义应用程序映像

    据我所知 在 Android 4 0 或更高版本 上 默认任务管理器显示程序的最后一个屏幕截图 程序图标没有左上角 看图片 我的问题是如何将任务管理器中的应用程序图像 不是图标 更改为自定义 别问我为什么 我只是需要 经过一番研究 我发现了
  • sed 中的“0,/xxx”是什么意思?

    脚本中使用的 sed 命令如下 sed i 0 ENABLE DEBUG s ENABLE DEBUG ENABLE DEBUG YES MakeConfig 我知道 s ENABLE DEBUG ENABLE DEBUG YES 是替换行
  • R:输出带有小计的类似数据透视表

    我正在尝试在 R 中进行交叉制表 并使其输出尽可能类似于 Excel 数据透视表中的输出 目标是用 R Markdown 自动生成的报告取代使用 Excel 和 Word 手动生成的报告 数据整理和图表已经处理完毕 但缺少一些表格 所以 给
  • 有没有比这更好的方法从 PrintDocument 获取页数?

    这是我想出的最好的 public static int GetPageCount PrintDocument printDocument printDocument PrinterSettings PrintFileName Path Ge
  • WebView不会播放任何声音

    我使用最简单的 WebView 实例 到目前为止 所需的一切都运行良好 除了播放声音之外 javascript 调用的声音和 html5 音频标签都无法通过此 WebView 工作 public class MainActivity ext
  • 如何重写另一个基类中的函数?

    我不太确定要使用的术语 但这是我的示例 class Base public virtual void test 0 class Mixin public virtual void test class Example public Base
  • 带有 Apache CXF 的 WS-Security UsernameToken

    我有一个与 SOAP 服务交互的 java 应用程序 我使用 WSDL 通过 CXF 生成 java 客户端 但我需要使用 ws security 来验证我的调用 我正在寻找一种纯代码方法来执行此操作 并且我没有任何 xml 配置 这是我尝
  • 如何在 Python 中读取通用数据格式 (CDF)

    我需要使用 python 读取 CDF 文件 我找到了图书馆 但我不明白如何使用它 例如在这个 Python 库 我需要下载CDF lib 我不知道在哪里下载 有 CDF 的下载页面 但似乎与该库无关 The answer miraculi
  • 如何以编程方式区分android中连接的蓝牙设备?

    是蓝牙耳机还是手机 如何在 Android 代码中区分蓝牙耳机和支持蓝牙的 Android 设备 我正在开发一个小型应用程序 因为我具有阻止通过蓝牙传输数据的功能 但它需要允许通过蓝牙耳机进行通信 我参考了他们建议我的示例和代码 仅配对 取
  • Hibernate @ManyToMany joinTable - OrderBy 使用连接表的字段

    有3张表 TABLE A ID A field1 fieldN TABLE B ID B field1 fieldN 表 A B ID A ID B订单字段 public class A ManyToMany JoinTable name
  • 支持文档中应包含哪些核心要素? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我创建了一个需要 移交 的应用程序下个月到支持小组 该应用程序是相当小 2个月开发 由两个客户端应用程序和一个数据库组成 它是用c 编写的 适用于Windows平台 我有一个广阔的想法支持
  • Android MediaRecorder - “启动失败:-19”

    我正在尝试在 Android 上创建一个录像机 并且我已经准备好了应该可以工作的代码 但我不断收到错误消息start failed 19 这是我的代码 public boolean startRecording try camera unl
  • 有什么简单的方法可以查看正在进行的 AJAX 调用?

    我正在寻找可以让我查看所有 AJAX 子请求的东西 最好是 Firefox 扩展 基本上 每当创建 XMLHTTPRequest 时 我想知道正在请求什么 URL 以及随之传递的 GET 和 POST 变量 如果有 除非我错过了 否则我在
  • 想了解异步

    我使用过一点异步编码 但我并没有真正完全理解如何使用它 尽管我理解这个概念以及为什么我需要它 这是我的设置 我有一个 Web API 我将从 ASP NET MVC 应用程序调用它 而我的 Web API 将调用 DocumentDB 在代