[英]Is there a ContinueWith for ValueTask?
If an API returns a ValueTask
or ValueTask<T>
, is there a way to perform a ContinueWith
on it, like I'm able to do with Task
?如果 API 返回ValueTask
或ValueTask<T>
,有没有办法对其执行ContinueWith
,就像我可以使用Task
一样? Is there a Microsoft-provided NuGet library for doing so with .NET Standard 2.0?是否有 Microsoft 提供的 NuGet 库与 .NET 标准 2.0 一起使用?
Use valueTask.AsTask()
.使用valueTask.AsTask()
。 AsTask()
is an escape hatch for just such use cases as yours. AsTask()
是像您这样的用例的逃生舱。 The purpose of ValueTask
is to avoid allocations whenever possible, but if you're going to invoke a continuation on another thread, you will need to allocate something and it might as well be a Task<T>
. ValueTask
的目的是尽可能避免分配,但如果您要在另一个线程上调用延续,您将需要分配一些东西,它也可能是一个Task<T>
。
Here you are:给你:
public static async ValueTask ContinueWith<TResult>(this ValueTask<TResult> source,
Action<ValueTask<TResult>> continuationAction)
{
// The source task is consumed after the await, and cannot be used further.
ValueTask<TResult> completed;
try
{
completed = new(await source.ConfigureAwait(false));
}
catch (OperationCanceledException oce)
{
var tcs = new TaskCompletionSource<TResult>();
tcs.SetCanceled(oce.CancellationToken);
completed = new(tcs.Task);
}
catch (Exception ex)
{
completed = new(Task.FromException<TResult>(ex));
}
continuationAction(completed);
}
A simpler implementation would be to Preserve
the ValueTask<TResult>
before the await
, and then invoke the continuationAction
passing the preserved task as argument.一个更简单的实现是在await
之前Preserve
ValueTask<TResult>
,然后调用continuationAction
将保留的任务作为参数传递。 This would cause invariably an allocation though, even in the case of the successful completion of the task.即使在成功完成任务的情况下,这也总是会导致分配。
The reason that I am avoiding the one-line Task.FromCanceled
method in the cancellation case, is because this method requires that the supplied CancellationToken
is canceled, otherwise it throws an ArgumentOutOfRangeException
.我在取消情况下避免使用单行Task.FromCanceled
方法的原因是因为此方法要求取消提供的CancellationToken
,否则会引发ArgumentOutOfRangeException
。
I know I am posting it too late.我知道我发布它为时已晚。 However wanted to share the approach I used...但是想分享我使用的方法......
ValueTask<T> vt = ValueTaskTReturningMethod();
var awt = vt.GetAwaiter();
awt.OnCompleted(() => {
T val = awt.GetResult();
//code you want to execute after async operation completes
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.