I made a quick example of the above at https://dotnetfiddle.net/v1kFjw, which creates the func, assigns it some potentially long-running work, adds some debug print statements as a timeline reference around it, then invokes it in both ways.
Using the View IL function, the following seems to be the difference, as korir stated:
Directly invoking the func creates the async
/await
state machine pattern around the code directly inside the func, then begins running the code inside the function until it hits await
, upon which the state machinery kicks in, 'returns' to the original caller (when I say returns, it's not a literal return, it's that the code following the invocation is silently wrapped up into the state machine), and continues, interleaved with calls to the awaited code, polling it for completion.
Using Task.Factory.StartNew
creates a new thread that runs regardless of what code is following it - this includes the program perhaps exiting before the thread you spun up even completes.
In the example, a continuation task to show completion had to be added, as well as a Task.WaitAll at the end to guarantee it finished.
I was just doing the research for interest's sake - if anyone has more insight or can point out flaws please do.
Edit: couple of things to note after I posted this: dotnetfiddle has execution time and output size restrictions which affects the results of the test - in the end I used Linqpad to do testing as that was more reliable. Also noted that calling the async function but not using the return value seemed to, again, run into the issue of not guaranteeing the full runtime of the function due to the main thread exiting before the result could finish.
In answer to your comment about .Unwrap()
not being used - ContinueWith()
doesn't seem to be compatible with it, at least according to the compiler.
In the end I defer to Stephen Cleary's answer as he is clearly more knowledgeable and qualified. :)
References: