2016-05-13 38 views
6

mam synchroniczny, metoda rodzajowa, który wygląda takCasting zadanie <T> do zadania <DerivedT>

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

pełnomocnika jest odniesienie usług WCF

To po prostu ma jedną metodę, która przyjmuje wniosek i zwraca odpowiedź. Ale jest używany przez przekazywanie pochodnych żądań i zwracanie wyprowadzonych odpowiedzi. Jak widać powyżej, metoda owijki odlewa odpowiedź do typu pochodnego określonego przez parametr ogólny (TResponse).

Wywołujesz metodę z wyprowadzonymi żądaniami i odpowiedziami:

np.

Execute<GetSomeDataResponse>(new GetSomeDataRequest()); 

jestem teraz generowanie odniesienie usług asynchronicznych, dzięki czemu można wykorzystać Zadania

Chciałbym więc metodę, która wygląda tak

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

który można nazwać jak ten

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

Potrzebuję więc sposobu na przesłanie Task<Response> do Task<TResponse>

Czytałem to co wydaje rodzaju przeciwieństwem tego, co muszę, ale nie mogę dowiedzieć się, jak bardzo zginać go do mojego użytku przypadku

How to convert a Task<TDerived> to a Task<TBase>?

jakieś pomysły?

+0

Cóż, zawsze można po prostu 'powrót (TDerived) (czeka na ExecuteRequestAsync (request)); '. – Luaan

+0

@Luaan niestety ExecuteRequestAsync nie jest metodą asynchroniczną w sensie .net 4.5 - po prostu zwraca zadanie . nie ma asynchronicznego słowa kluczowego w jego sygnaturze (generowane przez svcutil, więc nie mogę tego zmienić) – ChrisCa

+1

@ChrisCa ExecuteRequestAsync nie potrzebuje żadnego asynchronicznego słowa kluczowego, tak jak ExecuteAsync. – Evk

Odpowiedz

2

Łatwy sposób to użyć asynchronicznego \ czekają wzoru:

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

Nieco bardziej skomplikowany (wzięte z połączonego pytanie) jest użycie 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; 
} 
+0

ah - oczywiście. Nie mogę uwierzyć, że nie widziałem twojego pierwszego przykładu - dzięki! – ChrisCa

Powiązane problemy