c# - return Task.ContinueWith<TResult>() without knowing TResult -


how create , return continuation task using reflection or other means if have access task?

i need way let exception in continuation travel original caller. far know can done returning continuation task instead of original task. problem comes in don't know result type of task can't create proper continuation task.

edit: cannot change signature types. have many interfaces return task< tresult > objects , can't expect client task< object > results. these interfaces wcf contracts. want validation logic after "core" logic method done , throw exception if needed. exception must travel client not travel because i'm not returning continuation task yet. don't know type beforehand because i'm applying postsharp aspect , using onexit() override, gives me access return value know task can number of task objects of tresult known @ runtime.

using system; using system.threading.tasks;      namespace taskcontinuewith     {         internal class program         {             private static void main(string[] args)             {                 try                 {                     task<string> mytask = interceptor();                     mytask.wait();                 }                 catch (exception ex)                 {                     console.writeline(ex);                 }                  console.readline();             }              private static task<string> interceptor()             {                 task<string> task = corelogic(); //ignore                   task unknownreturntype = task; //this have access to. task object can 1 of numerous task<tresult> types known @ runtime.                  task continuation = unknownreturntype.continuewith(                     t =>                         {                          if(somecondition)                          {                              throw new exception("error");                          }                           return t.result; //this not work since don't know result.                      });                  return continuation;             }               private static async task<string> corelogic()             {                 return "test";             }         }     } 

another way express problem.

  1. i can change inside doextravalidation().
  2. i cannot change signature of doextravalidation() use generics.

how change doextravalidation make work task< tresult > return type?

using system; using system.threading.tasks;  namespace taskcontinuewith {     interface iservicecontract     {         task<string> dowork();     }      public class servce : iservicecontract     {         public task<string> dowork()         {             var task = task.fromresult("hello");             return  (task<string>) doextravalidation(task);         }          private static task doextravalidation(task task)         {             task returntask = null;             if (task.gettype() == typeof(task<string>))             {                 var knowntype = task task<string>;                 returntask = task.continuewith(                     t =>                     {                         if(new random().next(100) > 50)                         {                             throw new exception("error");                         }                         return knowntype.result;                      });             }             return returntask;         }     }      internal class program     {         private static void main(string[] args)         {             try             {                 iservicecontract myservice = new servce();                 task<string> mytask = myservice.dowork();                 mytask.wait();             }             catch (exception ex)             {                 console.writeline(ex);             }              console.readline();         }     } } 

sounds case dynamic. i'll try use little dynamic possible. first define strongly-typed helper:

static task<tresult> setcontinuation<tresult>(task<tresult> task) {     return task.continuewith(         t =>             {              if(somecondition)              {                  throw new exception("error");              }               return t.result;         }); } 

this function works, requires tresult known. dynamiccan fill in:

task continuation = setcontinuation((dynamic)unknownreturntype); 

i tested binding works @ runtime. alternatively can use reflection instead invoke helper (use methodinfo.makegenericmethod , others).


Comments