标签: valuetask

Task.CompletedTask 的 ValueTask 等价物是什么?

我正在实施IAsyncDisposable这要求我返回 a ValueTask,但有时我的 dispose 方法无关。在这种情况下我应该如何返回?

目前我正在返回new ValueTask(Task.CompletedTask)这似乎有效,但由于 valueTasks 的目的是避免创建不必要的堆对象,我相信应该有一种更简单、更有效的方法。

c# asynchronous task-parallel-library valuetask

16
推荐指数
2
解决办法
1582
查看次数

从内部等待某些任务的方法返回 ValueTask 是否有任何意义

我有一个异步方法,看起来大约像这样:

async Task<int> ParseStream()
{
    var a = await reader.ReadInt32();
    var b = await reader.ReadInt32();
    return a + b;
}
Run Code Online (Sandbox Code Playgroud)

由于数据已经准备好,因此该方法在大多数情况下都会同步工作。因此,用 ValueTask 替换返回类型以减少分配似乎是个好主意。但这会调用reader.ReadInt32()return Task。

所以问题是:从内部等待某些任务的方法返回 ValueTask 是否有意义?

c# async-await valuetask

5
推荐指数
1
解决办法
3802
查看次数

将 ValueTask&lt;T&gt; 转换为非泛型 ValueTask

这里提出的问题与这里的问题相同,旨在为其创建一个明确的解决方案。最准确的答案是 Stephen Toub 本人在本期中提出的,正是关于这个问题的。“推荐代码”如下:

public static ValueTask AsValueTask<T>(this ValueTask<T> valueTask)
{
    if (valueTask.IsCompletedSuccessfully)
    {
        valueTask.GetResult();
        return default;
    }

    return new ValueTask(valueTask.AsTask());
}
Run Code Online (Sandbox Code Playgroud)

这个答案不是最新的 - ValueTask 不公开 GetResult() (只有 Result 属性) - 问题是:

  • 我们是否需要将Result从ValueTask中“拉”出来(以“释放”这个ValueTask下可能操作的IValueTaskSource)?
  • 如果是:
    • .GetAwaiter()上面缺少的调用吗?
    • 或者对物业的假电话是否保证有效var fake = valueTask.Result;?总是?(我担心死代码消除。)
  • 如果不是,像下面这样的直接实现是否足够(并且是最佳的)?
public static ValueTask AsNonGenericValueTask<T>( in this ValueTask<T> valueTask )
{
    return valueTask.IsCompletedSuccessfully ? default : new ValueTask( valueTask.AsTask() );
}
Run Code Online (Sandbox Code Playgroud)

.net c# async-await valuetask

5
推荐指数
1
解决办法
1120
查看次数

为什么 Task&lt;T&gt; 比 ValueTask&lt;T&gt; 更快?

Task<T>我正在对和进行基准测试ValueTask<T>。源代码如下:

#LINQPad optimize+     // Enable compiler optimizations

void Main()
{
    Util.AutoScrollResults = true;
    BenchmarkRunner.Run<TaskAndValueTaskComparsion>();
}

[ShortRunJob]
public class TaskAndValueTaskComparsion
{
    [Benchmark]
    public ValueTask<int> RunValueTaskWithNew()
    {
        return new ValueTask<int>(1);
    }
    
    [Benchmark]
    public Task<int> RunTaskFromResult()
    {
        return Task.FromResult(1);
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

对于结果来说,Task<T>比 快得多ValueTask<T>。但为什么?我真的希望ValueTask<T>返回任务对象时会导致更少的分配。

c# asynchronous task valuetask

5
推荐指数
1
解决办法
1529
查看次数

如何选择异步委托的返回类型

我正在将异步委托传递给 LINQSelect方法,我更愿意获取ValueTasks列表而不是Tasks列表。我该怎么做?例子:

var result = (new[] { 0 }).Select(async x => await Task.Yield()).ToArray();
Console.WriteLine($"Result type: {result.GetType()}");
Run Code Online (Sandbox Code Playgroud)

结果类型:System.Threading.Tasks.Task[]

这是不可取的。我发现我可以通过用异步方法替换异步委托来创建我想要的列表,如下所示:

var result = (new[] { 0 }).Select(DoAsync).ToArray();
Console.WriteLine($"Result type: {result.GetType()}");
async ValueTask DoAsync(int arg)
{
    await Task.Yield();
}
Run Code Online (Sandbox Code Playgroud)

结果类型:System.Threading.Tasks.ValueTask[]

这有效,但很尴尬。有什么办法可以保持简洁的委托语法,并且仍然得到ValueTask我想要的s 吗?

c# task-parallel-library async-await valuetask

4
推荐指数
1
解决办法
145
查看次数

ValueTask.Preserve() 的意义是什么?

ValueTaskValueTask<TResult>有一个Preserve()方法概括为“获取可以在将来任何时候使用的 ValueTask”。

这是什么意思以及我们什么时候应该使用它?这是否意味着ValueTask“在未来的任何时候”都不能使用“正常”?如果是这样,为什么?

c# async-await valuetask

4
推荐指数
1
解决办法
693
查看次数

ValueTask 有 ContinueWith 吗?

如果 API 返回 aValueTaskValueTask<T>,有没有办法对其执行 a ContinueWith,就像我可以做的那样Task?是否有 Microsoft 提供的 NuGet 库用于使用 .NET Standard 2.0 执行此操作?

.net c# async-await valuetask

3
推荐指数
2
解决办法
507
查看次数

同步方法的 ValueTask

我正在使用并发字典来存储数据来实现一个简单的查找服务。由于使用此服务的大多数方法都是异步的,因此我正在考虑使用ValueTask<TResult>.

伪代码:

public ValueTask<string> GetResultAsync(string key)
{
 return ValueTask.FromResult(_dictionary.FirstOrDefault(p => p.Key == key).Value
}
Run Code Online (Sandbox Code Playgroud)

这种方法有意义吗?有什么注意事项吗?

c# asynchronous task valuetask

1
推荐指数
1
解决办法
96
查看次数

ValueTask 实例不应直接访问其结果,除非实例已经完成

有一个库返回 aValueTask并且我有一个消耗 ValueTask 的同步方法。问题是有以下警告:

CA2012:ValueTask 实例不应直接访问其结果,除非该实例已完成。与任务不同,在 ValueTask 上调用 Result 或 GetAwaiter().GetResult() 不能保证在操作完成之前阻塞。如果您不能简单地等待实例,请考虑首先检查其 IsCompleted 属性(或者如果您知道情况如此,则断言它是 true)。

我如何解决它?

public void CreateListenKey()
{
    var result = CreateSpotListenKeyAsync().GetAwaiter().GetResult(); // CA2012: ValueTask instances should not have their result directly accessed unless the instance has already completed. Unlike Tasks, calling Result or GetAwaiter().GetResult() on a ValueTask is not guaranteed to block until the operation completes. If you can't simply await the instance, consider first checking its IsCompleted property (or asserting it's true if you …
Run Code Online (Sandbox Code Playgroud)

.net c# valuetask

1
推荐指数
1
解决办法
1709
查看次数