ValueTask 有 ContinueWith 吗?
Is there a ContinueWith for ValueTask?
如果 API returns 一个 ValueTask
或 ValueTask<T>
,有没有办法对其执行 ContinueWith
,就像我能够与 Task
有什么关系?是否有 Microsoft 提供的 NuGet 库可用于 .NET Standard 2.0?
你在这里:
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);
}
一个更简单的实现是 Preserve
ValueTask<TResult>
在 await
之前,然后调用 continuationAction
将保留的任务作为参数传递。即使在成功完成任务的情况下,这也总是会导致分配。
我在取消情况下避免使用单行 Task.FromCanceled
方法的原因是因为此方法要求取消提供的 CancellationToken
,否则会抛出 ArgumentOutOfRangeException
.
使用valueTask.AsTask()
。 AsTask()
是像您这样的用例的逃生口。 ValueTask
的目的是尽可能避免分配,但如果你要在另一个线程上调用延续,你将需要分配一些东西,它也可能是 Task<T>
.
我知道我发布得太晚了。但是想分享我使用的方法...
ValueTask<T> vt = ValueTaskTReturningMethod();
var awt = vt.GetAwaiter();
awt.OnCompleted(() => {
T val = awt.GetResult();
//code you want to execute after async operation completes
}
如果 API returns 一个 ValueTask
或 ValueTask<T>
,有没有办法对其执行 ContinueWith
,就像我能够与 Task
有什么关系?是否有 Microsoft 提供的 NuGet 库可用于 .NET Standard 2.0?
你在这里:
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);
}
一个更简单的实现是 Preserve
ValueTask<TResult>
在 await
之前,然后调用 continuationAction
将保留的任务作为参数传递。即使在成功完成任务的情况下,这也总是会导致分配。
我在取消情况下避免使用单行 Task.FromCanceled
方法的原因是因为此方法要求取消提供的 CancellationToken
,否则会抛出 ArgumentOutOfRangeException
.
使用valueTask.AsTask()
。 AsTask()
是像您这样的用例的逃生口。 ValueTask
的目的是尽可能避免分配,但如果你要在另一个线程上调用延续,你将需要分配一些东西,它也可能是 Task<T>
.
我知道我发布得太晚了。但是想分享我使用的方法...
ValueTask<T> vt = ValueTaskTReturningMethod();
var awt = vt.GetAwaiter();
awt.OnCompleted(() => {
T val = awt.GetResult();
//code you want to execute after async operation completes
}