0

Task<T>我有一个方法可以在编译时获取一个where T is unknown 和一个IAsyncDisposable. 我需要返回一个Task<T>在原始任务完成后自动处理一次性对象的。

到目前为止,这是我想出的,但它引发了编译时错误

private static TResult AutoDispose<TResult>(TResult result, IAsyncDisposable asyncDisposable)
{
    Func<dynamic, dynamic> continuationFunction = async t => { await asyncDisposable.DisposeAsync(); return ((dynamic)t).Result; };
    var autoDisposing = ((dynamic)result).ContinueWith(continuationFunction);
    return (TResult)autoDisposing;
}

我得到的错误是

无法将异步 lambda 表达式转换为委托类型“Func<dynamic, dynamic>”。异步 lambda 表达式可能返回 void、Task 或 Task,它们都不能转换为 'Func<dynamic, dynamic>'。

我已经尝试了不同的组合,dynamicTask无法创建一个有效的解决方案。我总是遇到编译或运行时错误。

编辑

因为我为什么这样做似乎令人困惑:

我在IAsyncQueryProvidersExecuteAsync方法中使用它。接口定义方法签名如下

public TResult ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken = default)

基于此,我知道TResult是 typeIAsyncEnumerable<T>Task<T>. 我已经编写了代码来处理这种情况,但当IAsyncEnumerable<T>它是Task<T>.

4

2 回答 2

2

要使用async,编译时结果类型必须是Task(或类似任务的)。嵌套任务通常使用ContinueWith延续asyncUnwrap是一种解决方案。如果您可以ContinueWith完全避免,那就更好了,但我相信在这种情况下,这将需要相当多的繁琐的泛型工作。

像这样的东西应该工作:

private static TResult AutoDispose<TResult>(TResult result, IAsyncDisposable asyncDisposable) // where TResult: Task<T>
{
  Func<dynamic, Task<TResult>> continuationFunction = async () => { await asyncDisposable.DisposeAsync(); return result; };
  var continuation = ((dynamic)result).ContinueWith(continuationFunction, TaskScheduler.Default);
  var newResult = TaskExtensions.Unwrap(continuation);
  return (TResult)newResult;
}
于 2020-11-24T15:09:12.873 回答
0

尝试这个?

private static async Task<TResult> AutoDispose<TResult>( this Task<TResult> task )
    where TResult : IAsyncDisposable
{
    TResult result = await task.ConfigureAwait(false);
    if( result != null )
    {
        await result.DisposeAsync().ConfigureAwait(false);
    }
    
    return result;
}

示例用法:

Task<HttpResponseMessage> task = new HttpClient()
    .GetAsync( "/foo" )
    .AutoDispose();

HttpResponseMessage resp = await task;
// `resp` will be in a disposed state at this point.
于 2020-11-19T23:32:32.643 回答