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

在学习异步编程时,我一直在尝试实现一个既适用于异步类又适用于同步类的接口,但我看到了相互矛盾的做法。


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


public interface ILight

{

    void On();

    void Off();

}

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


public class WiredLight : ILight

{

    private bool _powered;


    public void On()

    {

        _powered = true;

    }


    public void Off()

    {

        _powered = false;

    }

}

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


public class WirelessLight : ILight

{

    public async Task On()

    {

        await EnablePowerAsync();

    }


    public async Task Off()

    {

        await DisablePowerAsync();

    }

}

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


public class WiredLight : ILight

{

    public Task OnAsync()

    {

        _powered = true;

        return Task.CompletedTask;

    }

}

但是在同步运行时将方法呈现为 Async 是谎言,并且也违反了建议。此外,看起来返回 aTask.CompletedTask可能会将相同的 Task 返回给不同的调用。我现在不知道这会在什么地方引起问题,但似乎会引起问题。


在不返回任何内容并且确实应该是同步的方法上实现异步接口是否有公认的做法?


忽然笑
浏览 206回答 1
1回答
打开App,查看更多内容
随时随地看视频慕课网APP