具有不可避免的异步等待调用的 ValueTask 方法?

我目前有以下异步方法:

private SomeObject _someObject = null;
public async Task<SomeObject> GetObjectAsync()
{
    await sslim.WaitAsync();
    if (_someObject == null)
    {
           _someObject = await InitializeSomeObjectAsync();          //starts calls to alot of async Task methods
    }
    sslim.Release();
   return _someObject;
}

如果上面的代码是一个热门路径并且被多次调用,那么改用Valuetask是否安全/可以?:

private SomeObject _someObject = null;
public async Valuetask<SomeObject> GetObjectAsync()
{
    await sslim.WaitAsync();
    if (_someObject == null)
    {
           _someObject = await InitializeSomeObjectAsync();          //starts calls to alot of async Task methods
    }
    sslim.Release();
   return _someObject;
}

我不确定的是 sslim.WaitAsync 锁定调用,它总是会导致代码路径永远不会完全同步(即使 _someObject 已经初始化),这与将 Valuetask 用于可能的路径相反同步执行?

另一个想法,也许将 SemaphoreSlim 调用更改为同步版本也有意义?

private SomeObject _someObject = null;
public async Valuetask<SomeObject> GetObjectAsync()
{
    sslim.Wait();
    if (_someObject == null)
    {
           _someObject = await InitializeSomeObjectAsync();          //starts calls to alot of async Task methods
    }
    sslim.Release();
   return _someObject;
}

我计划对上述变体进行一些基准测试,但只是想从更了解哪些选项值得考虑的人那里获得一些反馈。

谢谢。

lookme123 回答:具有不可避免的异步等待调用的 ValueTask 方法?

我不确定的是 sslim.WaitAsync 锁定调用,它总是会导致代码路径永远不会完全同步

我不确定为什么会这样。异步方法可能同步运行,如果信号量可用,我希望 SemaphoreSlim.WaitAsync 同步获取信号量。

对于可以同步执行的路径,这与使用 ValueTask 有什么矛盾?

即使它异步完成,使用 ValueTask<T> 也可以让您的代码避免为每次调用分配 Task<T>。如果它同步完成,它甚至效率更高,但即使它始终是异步的,您也会获得一些效率优势。

我目前有以下异步方法

您可能对AsyncLazy<T> (with AsyncLazyFlags.RetryOnFailure)感兴趣。它使用 Task<T>,但一旦初始化成功完成,它就无需分配(始终返回相同的 Task<T> 实例)。

本文链接:https://www.f2er.com/3231.html

大家都在问