I have a method
public Task<Task> DoSomeWorkOnARemoteMachine()
which, very descriptively, executes some work on a remote machine by:
The reason I used Task<Task>
is because the first Task<>
is for the queueing of the message; while the inner Task
is completed when the work has been completed on the remote machine (i.e. when the message from the agent has been received). Any exceptions which the remote agent caught during execution of the work are passed along with the completion message and are re-thrown when the inner Task
completes.
To call this method I use:
await await DoSomeWorkOnARemoteMachine();
which would wait for the message to be queued to execute the job, as well as to complete the job and receive any exceptions. However, if I was not interested in whether the job completed on the remote agent or not, I might call it as follows:
await DoSomeWorkOnARemoteMachine();
which would not await
the inner Task
. However, the inner Task
(which receives the message from the remote agent, and re-throws the exceptions) would still execute at some point. I feel that this is a bit of a waste and I would like to avoid executing it when I don't await
for the results.
My question is thus: is it possible for a Task
to "know" whether it is being await
ed and not execute if it is not, or execute some other code path (such as an empty Task
body).
I do realize that there are alternatives that I could implement, such as passing a "fire and forget" flag, or adding an overload for "fire and forget". It would be great though if I could implement this without the client API changing
Answers involving other projects which implement this sort of remote work execution would also be great!
If it is some trivial operation that executes quickly, then you can just call it synchronously, without the need for await . But if it is a long-running operation, you may need to find a way to make it asynchronous.
If you don't await the task or explicitly check for exceptions, the exception is lost. If you await the task, its exception is rethrown. As a best practice, you should always await the call. By default, this message is a warning.
So, yes, you can await already completed tasks. Note that, if you call await several time, it will return it every time and by reference if it's not a value.
I dont think it's easily or efficiently achievable (playing with Task.GetAwaiter is a bad idea, and it will not be accessible from inside your function, see Noseratio's answer). Here is alternative solutions :
Solution n°1 : Function parameter for Task
execution
await DoSomeWorkOnARemoteMachine(false) //Indicates that DoSomeWork shouldn't be executed
Solution n°2 : Explicit Task Execution
Task t = await DoSomeWorkOnARemoteMachine() ;
t.Start(); // For example, if you want to execute the resulting Task.
// You can also dispatch it to an other thread, etc...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With