Immediately assignment for a call built inside a ContinueWith block?
First, an apology for the title; I couldn't think of a way to summarize what I am trying to do.
I have the following two functions:
Main code:
private async Task<PreparationInfo> PrepareRoundtrip()
{
PreparationInfo output = new PreparationInfo();
Task.Delay(3000); // stands in for a call to the server to fetch data for how to prepare
prepare(output) // package result into output
return output;
}
private Task ExecuteWithPrepare()
{
if (!PrepareEnabled) // instance variable
return stateObject.Execute();
else
{
Task<PreparationInfo> prepareTask = PrepareRoundtrip();
return tceTask.ContinueWith((prepareTaskInternal) =>
{
stateObject.Execute(); // this is the Task that I need to return
});
}
}
stateObject.Execute () header:
internal Task Execute()
{
...
}
I am writing a wrapper for a method stateObject.Execute()
that will pre-request a prepare ( PrepareRoundtrip()
) method to handle some parameters before executing.
If preparation is not activated ( PrepareEnabled == false
), I can just call the direction Execute()
and immediately return the returned task. If provisioning is enabled, I need to run the provisioning method (which is unique to this task, I can modify it as needed), then run Execute()
.
The part I'm stuck on is:
The entire function should run and return as if it were stateObject.Execute()
called directly, with only the part added PrepareRoundtrip()
, which meant two things:
-
The task returned from
ExecuteWithPrepare()
must represent the task being returnedstateObject.Execute()
. -
ExecuteWithPrepare()
should return immediately (i.e. not wait for the 3 second delay inPrepareRoundtrip()
What's the best way to achieve this? Thank!
TL; DR:
Adding a wrapper stateObject.Execute()
to add an extra preparation step that is potentially long; everything is needed to immediately return a task that represents the original result, and not wait for the completion of the first stage of preparation.
source to share
You shouldn't use ContinueWith
at all. This is a deprecated method with dangerous behavior (in particular, it will use the current task scheduler).
Instead, just use await
:
private Task ExecuteWithPrepareAsync()
{
if (!PrepareEnabled)
return stateObject.ExecuteAsync();
else
return PrepareAndExecuteAsync();
}
private async Task PrepareAndExecuteAsync()
{
await PrepareRoundtripAsync();
await stateObject.ExecuteAsync();
}
Also notice the naming convention Async
, part of the TAP pattern .
source to share