繁体   English   中英

投放任务 <T> 任务 <DerivedT>

[英]Casting a Task<T> to a Task<DerivedT>

我有一个类似的同步通用方法

public TResponse Execute<TResponse>(Request request) where TResponse : Response
{
   return (TResponse) proxy.ExecuteRequest(request);

代理是WCF服务参考

它只有一种接受请求并返回响应的方法。 但是通过传递派生的请求并返回派生的响应来使用它。 正如您在上方看到的那样,包装器方法将响应转换为由通用参数(TResponse)指定的派生类型。

您使用派生的请求和响应来调用方法

例如

Execute<GetSomeDataResponse>(new GetSomeDataRequest());

我现在正在生成一个异步服务引用,因此可以利用Tasks

所以我想要一个看起来像这样的方法

public Task<TResponse> ExecuteAsync<TResponse>(Request request) where TResponse : Response
{
    // need to cast to a Task<TResponse>
    return proxy.ExecuteRequestAsync(request

可以这样称呼

Task<GetSomeDataResponse> res = ExecuteAsync<GetSomeDataResponse>(new GetSomeDataRequest());

所以我需要一种将Task<Response> Task<TResponse>转换为Task<TResponse>

我一直在阅读这似乎与我需要的相反,但无法完全弄清楚如何将其适应我的用例

如何将Task <TDerived>转换为Task <TBase>?

有任何想法吗?

简单的方法是使用async \\ await模式:

 public static async Task<TResponse> ExecuteAsync<TResponse>(Request request) where TResponse : Response {
    var response = await proxy.ExecuteRequestAsync(request);
    return (TResponse) response;
 }

使用TaskCompletionSource更复杂(从您的链接问题中获取):

public static Task<TResponse> ExecuteAsync2<TResponse>(Request request) where TResponse : Response {
    var tcs = new TaskCompletionSource<TResponse>();
    proxy.ExecuteRequestAsync(request).ContinueWith(t => {
        if (t.IsFaulted)
            tcs.TrySetException(t.Exception.InnerExceptions);
        else if (t.IsCanceled)
            tcs.TrySetCanceled();
        else
            tcs.TrySetResult((TResponse) t.Result);
        }, TaskContinuationOptions.ExecuteSynchronously);
    return tcs.Task;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM