当前位置: 首页 > 知识库问答 >
问题:

在同步对象中实现异步接口

阎善
2023-03-14

null

例如,如果我试图用On()和Off()方法实现一个 接口。

public interface ILight
{
    void On();
    void Off();
}

使用 ,这些方法是同步的,并且都是快速的CPU绑定工作。

public class WiredLight : ILight
{
    private bool _powered;

    public void On()
    {
        _powered = true;
    }

    public void Off()
    {
        _powered = false;
    }
}

但是使用 ,这些方法是异步的,其中有IO绑定的工作。(这里的方法不遵循接口签名,而是作为异步实现,以避免异步无效。)

public class WirelessLight : ILight
{
    public async Task On()
    {
        await EnablePowerAsync();
    }

    public async Task Off()
    {
        await DisablePowerAsync();
    }
}

阅读(这里和这里),这样做的方法只是强制接口中的异步签名,然后所有的同步调用将被重构为异步(ref:Async all the way)。这听起来不错,但我还没有真正了解应该如何处理同步方法(来自 )。与这个问题不同的是,没有IO绑定操作,因此没有什么可等待的。我考虑过将它们包装在异步调用中(codeReturn task.run(()=&>{_powered=true;)/code),但这与大多数建议相反。我还考虑过简单地返回一个已经完成的任务(类似于这个或这个)

public class WiredLight : ILight
{
    public Task OnAsync()
    {
        _powered = true;
        return Task.CompletedTask;
    }
}

但是在同步运行时将方法表示为异步是错误的,而且也不利于重新协作。此外,看起来返回一个 可能会将相同的任务返回给不同的调用。我现在不知道这在哪里会引起问题,但它似乎是一些会引起问题的东西。

在一个不返回任何东西,实际上应该是同步的方法上实现一个异步接口,有没有一个公认的实践?

共有1个答案

施弘壮
2023-03-14

从同步方法中执行异步操作可能非常危险。没有完美的方法可以做到这一点,而且您可能经常会陷入线程不足问题的僵局。这不是你想要的情况。

另一方面,从异步方法执行同步操作是安全的。当然,您在对调用者撒谎,但这并不是真正的问题,除非他希望并行执行您的代码(在这种情况下,一旦他注意到这个问题,他只需添加一个 ,您也应该在注释中提到这个问题)。当等待一个已完成的任务时,运行库足够聪明,可以优化调用,因此对调用者的性能影响非常小,对于大多数应用程序来说可以忽略不计。

因此,如果您有理由认为需要在接口的某个实现中执行异步代码,请不要犹豫,将其标记为异步代码。对于实际上是同步的实现,返回一个已完成的任务通常是最好的做法:

public Task DoSomethingAsync()
{
    DoSomething(); 
    return Task.CompletedTask;
}

我建议不要在方法内部使用 ,因为它通常是不希望的,而且如果需要,调用方可以很容易地添加它。NET中的 意味着该方法可以异步完成,而不是快速返回。

 类似资料:
  • 问题内容: 我有一个Web应用程序正在进行负载/性能测试,特别是在一项功能上,我们希望数百名用户正在访问同一页面,并且每10秒刷新一次。我们发现可以使用此功能进行改进的一个方面是,由于数据未更改,因此将Web服务的响应缓存了一段时间。 在实现了基本的缓存之后,在进一步的测试中,我发现我没有考虑并发线程如何同时访问缓存。我发现在大约100毫秒内,约有50个线程试图从缓存中获取对象,发现对象已过期,点

  • 本文向大家介绍不同js异步函数同步的实现方法,包括了不同js异步函数同步的实现方法的使用技巧和注意事项,需要的朋友参考一下 不同函数达到同步的函数模拟 funcList是函数执行函数的队列,其中回调函数中flag=true是同步标记量 以上这篇不同js异步函数同步的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。

  • 问题内容: 我该如何做这项工作 我试图从异步之一获取同步功能,我需要它来使用FreeTds异步查询作为同步之一 问题答案: 使用deasync-用C ++编写的模块,它将Node.js事件循环暴露给JavaScript。该模块还公开了一个函数,该函数阻止后续代码,但不阻止整个线程,也不引起繁忙的等待。您可以将函数放入循环中:

  • 我正在寻找有关同步块的澄清。考虑一下这个类 - A是单例。getValue在整个应用程序中被多个线程大量访问。我添加了一个新方法remove,它从映射中删除一个键。如果如上所述执行删除, 当线程位于remove方法的同步块中时,我假设它将获取map对象上的锁。这是否意味着其他试图通过getValue方法访问映射的线程将被阻止?(我希望他们这样做。) 当remove方法的同步块中没有线程时,访问ge

  • 我意识到这是一个基本问题,但我没能在别处找到答案。 是

  • 问题内容: 同步和异步AJAX调用有什么区别?何时使用同步以及何时异步? 问题答案: 在最基本的级别上,当您希望调用在后台发生时,您可以使用异步模式,而当您希望代码等待直到调用完成时,则可以使用同步模式。 异步模式是AJAX调用的常用方法,因为通常在事件上附加一个回调函数,以便您可以在服务器端数据就绪时进行响应,而不必等待数据到达。

  • 问题内容: 由于Servlet 3.0 支持异步处理。使用始终异步处理会更好吗?或者在什么情况下同步处理更好? 问题答案: 异步Servlet带来的最大好处是HTTP push ,在该服务器中,服务器可以在选择时向客户端发送信息,而不是在客户端请求时将信息发送回客户端。在异步Servlet之前,这将需要长时间运行的HTTP连接,每个HTTP连接都会束缚服务器线程,这是非常低效的。这个新模型使服务器

  • 主要内容:同步时钟,实例,实例,异步时钟关键词: 同步,异步 由第 3 章可知,当触发器输入端的数据和触发器的时钟不相关时,很容易导致电路时序不满足。本章主要解决模块间可导致时序 violation 的异步问题。 关于异步与同步的定义,许多地方都有介绍,细节上也有所差异。本章主要的关注点是解决异步问题的方法,而不关心为什么会出现异步时钟,也不关心异步电路的具体结构,仅从异步时钟的时序结果去分析解决问题。 同步时钟 数字设计中,一般认为,