Questions tagged «async»

5
C#中异步/等待用法的准则是否与好的架构和抽象分层的概念相矛盾?
这个问题与C#语言有关,但我希望它涵盖其他语言,例如Java或TypeScript。 Microsoft建议在.NET中使用异步调用的最佳做法。在这些建议中,让我们选择两个: 更改异步方法的签名,以便它们返回Task或Task <>(在TypeScript中,这将是Promise <>) 更改异步方法的名称以xxxAsync()结尾 现在,当用异步组件替换低级同步组件时,这会影响应用程序的整个堆栈。由于异步/等待仅在“一直使用”时才有积极影响,因此这意味着必须更改应用程序中每一层的签名和方法名称。 好的体系结构通常涉及在每个层之间放置抽象,这样高层组件就看不到用其他组件替换低层组件。在C#中,抽象采用接口的形式。如果我们引入了一个新的,低级的异步组件,则调用堆栈中的每个接口都需要修改或替换为一个新接口。在实现类中解决问题(异步或同步)的方式不再对调用方隐藏(抽象)。调用者必须知道它是同步还是异步。 异步/等待与“良好架构”原则相抵触的最佳做法吗? 这是否意味着每个接口(例如IEnumerable,IDataAccessLayer)都需要它们的异步对应项(IAsyncEnumerable,IAsyncDataAccessLayer),以便在切换到异步依赖项时可以在堆栈中对其进行替换? 如果我们进一步推论这个问题,那么假设每个方法都是异步的(返回Task <>或Promise <>),并且使方法在实际上不是实际的情况下同步,会不会更简单?异步?这是将来的编程语言所期望的吗?
103 c#  architecture  async 

5
功能语言中的异步编程
我主要是C / C ++程序员,这意味着我的大部分经验都涉及过程和面向对象的范例。但是,正如许多C ++程序员所知道的那样,多年来,C ++的重点已转移到具有功能的风格,最终在C ++ 0x中增加了lambda和闭包。 无论如何,尽管我在使用C ++ 进行功能样式编码方面有丰富的经验,但是我对诸如Lisp,Haskell等实际功能语言的经验却很少。 我最近开始研究这些语言,因为纯功能语言中的“无副作用”的想法一直吸引着我,特别是在将其应用于并发和分布式计算方面。 但是,出于C ++的背景,我对于这种“无副作用”的哲学与异步编程的工作方式感到困惑。异步编程是指可以分发用户提供的事件处理程序以处理异步发生的事件(程序流之外)的任何框架/ API /编码样式。这包括异步库,例如Boost.ASIO,甚至只是普通的C语言。信号处理程序或Java GUI事件处理程序。 所有这些共同点是,异步编程的性质似乎需要创建副作用(状态),以使程序的主要流程意识到已调用了异步事件处理程序。通常,在Boost.ASIO之类的框架中,事件处理程序会更改对象的状态,从而使事件的影响传播到事件处理程序功能的生存期之外。真的,事件处理程序还能做什么?它不能“返回”值到调用点,因为没有调用点。事件处理程序不是程序主流程的一部分,因此它对实际程序有任何影响的唯一方法是更改​​某些状态(或更改longjmp为另一个执行点)。 因此,似乎异步编程是关于异步产生副作用的。这似乎与函数式编程的目标完全矛盾。这两种范例在功能语言中如何进行协调(实际上)?

4
是什么决定哪些Javascript函数正在阻塞与非阻塞?
几年来,我一直在做基于Web的Javascript(香草JS,jQuery,Backbone等),最近我正在与Node.js做一些工作。我花了一段时间才能摆脱“非阻塞”编程的束缚,但是我现在已经习惯于将回调用于IO操作等等。 我了解Javascript本质上是单线程的。我了解节点“事件队列”的概念。我不明白是什么决定了单个javascript操作是“阻止”还是“非阻止”。我如何知道我可以依靠哪些操作来同步生成输出供我在以后的代码中使用,以及我需要将哪些回调传递给我以便在初始操作完成后处理输出?在某个地方是否存在异步/非阻塞的Javascript函数列表,以及同步/阻塞的Javascript函数列表?是什么阻止我的Javascript应用成为一种激烈的竞争状况? 我知道需要很长时间的操作,例如Node中的IO操作和Web上的AJAX操作,要求它们是异步的并因此使用回调-但是谁在确定什么才是“长时间”?这些操作中是否有某种触发器可以将其从正常的“事件队列”中删除?如果不是,那么它们与简单的操作(如为变量赋值或遍历数组)之类的简单操作有何不同?似乎我们可以依靠它们以同步方式完成操作? 也许我什至没有正确地考虑这一点-希望有人可以让我直率。谢谢!

6
您为什么要“等待”一个方法,然后立即查询它的返回值?
在本文中,提供了以下示例代码(为简便起见,对其进行了略作编辑): public async Task<ActionResult> Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Department department = await db.Departments.FindAsync(id); if (department == null) { return HttpNotFound(); } return View(department); } 该FindAsync方法Department通过其ID 检索对象,并返回Task<Department>。然后立即检查部门以查看其是否为空。据我了解,以这种方式要求Task的值将阻止代码执行,直到返回了来自waited方法的值,从而有效地使它成为同步调用。 你为什么要这样做?Find(id)如果您要立即阻止,仅调用sync方法不是更简单吗?
24 c#  .net  asp.net-mvc  async 

3
如何诊断异步/等待死锁?
我正在使用大量使用异步/等待的新代码库。我团队中的大多数人对于异步/等待也是相当陌生的。我们通常倾向于遵循Microsoft指定的最佳实践,但是通常需要我们的上下文来传递异步调用并使用不支持的库ConfigureAwait(false)。 结合所有这些内容,我们每周都会遇到文章中描述的异步死锁。它们不会在单元测试期间显示,因为我们的模拟数据源(通常通过Task.FromResult)不足以触发死锁。因此,在运行时或集成测试期间,某些服务调用只会吃到午餐,再也不会返回。那会杀死服务器,并且通常使事情变得一团糟。 问题在于,要跟踪错误的出处(通常只是一直不完全同步),通常涉及手动代码检查,这很耗时且无法自动化。 诊断死锁的更好方法是什么?
24 c#  debugging  async 

5
在什么时候异步读取磁盘I / O比同步更有效?
假设有一些代码可以读取多个使用者的文件,并且文件的大小是任意的:异步读取文件的效率如何提高?或者换一种说法,要同步读取文件,文件必须快到多小? 我注意到(也许我不正确),当读取非常小的文件时,异步读取它们比同步读取(尤其是.NET)需要更长的时间。我假设这与设置时间有关,例如I / O完成端口,线程等。 有什么经验法则可以帮助您吗?还是取决于系统和环境?
22 efficiency  async  io 

2
谁先进行了异步/等待?
Python在2015年在3.5中添加了async / await构造。Javascript社区朝着它迈进了一大步,并在2017年发布的ES8草案中增加了非常相似的实现(据我了解)。Typescript在2015年的1.7版中还添加了异步方法,使未经训练的人看起来完全像js异步方法。 C#在2012年添加了异步方法,这些方法看起来与async / await的所有其他实现类似,并且基于F#的行为类似但外观不同的异步工作流,该工作流于2010年在F#2.0中引入。这是我所知道的最早关于异步编程语言的示例-具有异步/等待对的C#和具有异步流的F#。 是否有较早的示例在此上下文中将关键字用作语言构造(或库)?从我有限的信息来看,似乎每个人都模仿了C#实现的优秀部分,但是C#是否从其他人那里复制了它呢?

3
并行调用多个异步服务
我很少有彼此不依赖的异步REST服务。那就是在“等待” Service1的响应时,我可以调用Service2,Service3等。 例如,参考下面的代码: var service1Response = await HttpService1Async(); var service2Response = await HttpService2Async(); // Use service1Response and service2Response 现在,它们service2Response不再依赖service1Response并且可以独立获取。因此,不需要我等待第一服务的响应来呼叫第二服务。 我不认为我可以Parallel.ForEach在这里使用,因为它不是CPU限制的操作。 为了并行调用这两个操作,可以调用use Task.WhenAll吗?我看到的一个问题Task.WhenAll是它不会返回结果。要获取结果,我可以在致电task.Result后调用Task.WhenAll,因为所有任务都已经完成并且我需要获取我们所有的响应? 样例代码: var task1 = HttpService1Async(); var task2 = HttpService2Async(); await Task.WhenAll(task1, task2) var result1 = task1.Result; var result2 = task2.Result; // Use result1 and result2 就性能而言,此代码是否比第一个更好?我可以使用其他方法吗?

3
BackgroundWorker与异步/等待
我是C#开发的新手,希望创建一个响应更快的UI。在我的初步研究中,我看到了两种实现此目的的方法: 与BackgroundWorker类结合使用多线程。 较新的异步/等待修饰符。 更新意味着更好吗?两种方法有什么区别?如果我想创建一个新项目,如何选择哪种方法? 编辑:也许我应该指定。我正在创建一个Windows Forms应用程序,其中所有必需的数据都将保存/加载到本地磁盘上。我还将与多个USB设备通信。

2
为什么C#允许您进行重写异步?
在C#中,当您覆盖方法时,允许在未使用原始方法的情况下进行覆盖异步。这似乎是糟糕的形式。 使我想到这一点的例子是这样-我是来协助进行负载测试问题的。在大约500个并发用户的情况下,登录过程将在重定向循环中分解。IIS正在记录异常,并显示消息“异步模块或处理程序在异步操作仍处于挂起状态时已完成”。一些搜索使我认为有人在滥用async void,但是我快速搜索源却找不到任何东西。 可悲的是,当我本应寻找诸如“ async \ s [^ T]”之类的东西时,我正在搜索“ async \ svoid”(正则表达式搜索)(假设Task尚未完全合格……您明白了)。 后来我发现是async override void onActionExecuting(...在基本控制器中。显然,这一定是问题所在。解决该问题(暂时使其同步)解决了该问题。 回到问题:为什么当调用代码永远无法等待覆盖时,为什么还要将覆盖标记为异步?
16 c#  async 

3
C#5异步支持将如何帮助解决UI线程同步问题?
我在某处听说C#5 async-await非常棒,您不必担心这样做: if (InvokeRequired) { BeginInvoke(...); return; } // do your stuff here 看起来,等待操作的回调将在调用者的原始线程中发生。埃里克·利珀特(Eric Lippert)和安德斯·海斯伯格(Anders Hejlsberg)多次指出,此功能源于使UI(尤其是触摸设备UI)具有更高响应能力的需求。 我认为此类功能的常见用法如下: public class Form1 : Form { // ... async void GetFurtherInfo() { var temperature = await GetCurrentTemperatureAsync(); label1.Text = temperature; } } 如果仅使用回调,则设置标签文本将引发异常,因为未在UI线程中执行该文本。 到目前为止,我找不到任何资源可以证实这种情况。有人知道吗?是否有任何文件从技术上解释这将如何工作? 请提供可靠来源的链接,而不仅仅是回答“是”。

6
C#5异步重入的解决方案
因此,关于C#5中新的异步支持的问题一直困扰着我: 用户按下一个按钮即可启动异步操作。呼叫立即返回,并且消息泵再次开始运行-这就是重点。 因此,用户可以再次按下按钮-导致重新进入。如果有问题怎么办? 在我看到的演示中,他们在await通话前禁用了按钮,然后在通话后再次启用了该按钮。在我看来,这似乎是现实应用中非常脆弱的解决方案。 我们是否应该编写某种状态机来指定必须为给定的一组运行操作禁用哪些控件?或者,还有更好的方法? 我很想在操作过程中只显示一个模式对话框,但这有点像使用大锤。 有人有什么好主意吗? 编辑: 我认为禁用在操作运行时不应该使用的控件是脆弱的,因为我认为当您拥有带有许多控件的窗口时,它很快就会变得很复杂。我喜欢使事情简单,因为在初始编码和后续维护期间,它减少了错误的机会。 如果存在针对特定操作应禁用的控件集合,该怎么办?如果同时执行多个操作怎么办?

1
NodeJS如何实现“非阻塞”?
我正在学习NodeJS,只是想澄清一些东西。到目前为止,在几本入门教程和书籍中,它们很早就描述了Node的“非阻塞”体系结构-或者说有可能(并建议整个观点)以非阻塞方式进行编码。 因此,例如,在我正在阅读以异步方式从数据库获取数据的书中给出了此示例。 http.createServer(function (req, res) { database.getInformation(function (data) { res.writeHead(200); res.end(data); }); }); 据我所知,发生的事情是Node调用了数据库,然后继续处理调用堆栈中下一步可能发生的任何事情。数据库请求完成后,将填充匿名回调函数中的数据变量,并将该函数添加到调用堆栈中(并在Node到达该堆栈时执行)。 我的问题是,究竟在处理数据库请求是什么?当然,Node必须同时阻止吗?负责数据库请求的是什么?或者,如果Node在等待对外部资源的异步HTTP GET请求,那么该请求又在做什么呢?

2
什么时候应该使用StringBuilder或StringBuffer?
在生产型Web应用程序中,我的同伴程序员在各处都使用StringBuffer。现在,我负责应用程序的开发和更正。阅读StringBuilder和StringBuffer之后,我决定将所有StringBuffer代码替换为StringBuilder,因为我们不需要数据bean中的线程安全。 例如:(在每个数据bean中,我都可以看到StringBuffer的使用) @Override public String toString() { StringBuffer sb = new StringBuffer();// replace it from StringBuilder sb.append(" ABCD : ").append(abcd); sb.append(", EFGH : ").append(efgh); sb.append(", IJKL : ").append(ijkl); } 我们为每个会话/请求创建一个单独的数据bean。会话由单个用户使用,其他用户无法访问它。 在迁移之前,我还应该考虑其他几点吗? 如果只有一个线程(没有等待线程/没有新线程将寻找对象锁定),则它与StringBuffer或StringBuilder的性能相同。我知道在使用StringBuffer的情况下,需要花费时间来获取对象锁,但是我想知道除了保持/释放对象锁外,它们之间是否存在任何性能差异。

2
准备就绪与完成异步IO内存使用情况?
我看这次谈话有关实现异步IO在锈和卡尔提到了两个潜在的车型。准备和完成。 准备模型: 您告诉内核您要从套接字读取 暂时做其他事情…… 内核会告诉您套接字准备就绪的时间 您阅读(填充缓冲区) 做你需要的一切 释放缓冲区(Rust自动发生) 完成模型: 您为内核分配缓冲区以填充 暂时做其他事情…… 内核会告诉您何时缓冲区已满 对数据做您需要做的一切 释放缓冲区 在使用准备模型的卡尔例如,你可以遍历准备插槽填充和释放一个全球性的缓冲,这使得它看起来像它会使用很多的内存更少。 现在我的假设是: 在底层(在内核空间中),当套接字被称为“就绪”时,数据已经存在。它已通过网络(或从任何地方)插入套接字,并且OS保留了数据。 这似乎并没有在准备模型中神奇地发生内存分配。只是操作系统正在从您那里提取它。在完成模型中,操作系统要求您在数据实际流入之前分配内存,这很明显正在发生。 这是我对“就绪模型”的修订版: 您告诉内核您要从套接字读取 暂时做其他事情…… 修订:数据进入操作系统(内核内存中的某个位置) 内核告诉您套接字已准备好 阅读(填充另一个与上述内核缓冲区分开的缓冲区(或者得到指向它的指针?)) 做你需要的一切 释放缓冲区(Rust自动发生) /我的假设 我碰巧喜欢将用户空间程序保持在很小的位置,但是我只是想澄清一下实际情况。我看不到一个模型会固有地使用更少的内存或支持更高级别的并发IO。我很想听听对此的想法和更深入的解释。
12 async  io 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.