New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ContinueWith overloads #16
Conversation
Add ContinueWith overloads with the state parameter
/// <param name="task">The target Task</param> | ||
/// <param name="action">The continuation method to execute</param> | ||
/// <param name="state">A state object to pass to the continuation</param> | ||
/// <returns>A task representing the continuation status</returns> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about copying the documentation from https://github.com/Microsoft/referencesource/blob/b31308b03e8bd5bf779fb80fda71f31eb959fe0b/mscorlib/system/threading/Tasks/Task.cs#L3932-L3948?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea of copying the documentation also brings to light that the BCL uses the parameter name continuationAction
which we should follow for source compatibility if people use named parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it!
I would feel most comfortable with test coverage of every code path, boring as that is. 😬 Sorry to be a stick-in-the mud!
private sealed class ContinueWithState | ||
{ | ||
private readonly Action<Task, object> _Callback; | ||
private readonly object _State; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've never seen the _Upper
naming convention before. I apologize that we don't have an .editorconfig set up.
The polyfill code, copying Microsoft, uses m_camelCase
. My personal preference for private fields would be camelCase
but if you don't like that, _camelCase
would be fine.
/// <param name="task">The target Task</param> | ||
/// <param name="action">The continuation method to execute</param> | ||
/// <param name="state">A state object to pass to the continuation</param> | ||
/// <returns>A task representing the continuation status</returns> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea of copying the documentation also brings to light that the BCL uses the parameter name continuationAction
which we should follow for source compatibility if people use named parameters.
/// <returns>A task representing the continuation status</returns> | ||
public static Task ContinueWith(this Task task, Action<Task, object> action, object state) | ||
{ | ||
return task.ContinueWith(new ContinueWithState(action, state).ContinueWith); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please match BCL behavior by throwing new ArgumentNullException(nameof(continuationAction))
. Right now ContinueWithState.ContinueWith
throws a NullReferenceException when the continuation executes rather than throwing an ArgumentNullException before even scheduling the continuation, as the BCL does.
(That's a reminder to me that we need tests verifying this behavior too.)
Added XML documentation from ReferenceSource Changed parameter names to be compatible
So, apparently the AsyncTargetingPack does not include any ContinueWith extension methods. I'll have to disable the ContinueWith tests for that target. |
Added ContinueWith overload tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last thing I missed until I ran code coverage! I added integration with codecov.io, so if you rebase the PR on the latest updates to master, you'll get to see it here.
public void Action() | ||
{ | ||
var GotState = false; | ||
TestUtils.RunAsync(() => TaskEx.Run(() => { }).ContinueWith((task, state) => GotState = (bool)state, true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't actually testing the Action<Task, object>
overload. Because of the lambda's expression body, the compiler is inferring it as Func<Task, object, bool>
.
You can see that by the red lines in the coverage report here: https://codecov.io/gh/OmerMor/AsyncBridge/src/2806bdff8e65cfb4be247c1595fc319cdc3baa19/src/AsyncBridge/AsyncCompatLibExtensions.cs#L779...797
(needs to be fixed in 5 places)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn it! I'll fix that up.
One thing I really miss from SharpDevelop is the code coverage integration. VS only offers it in the enterprise version.
public void ActionResult() | ||
{ | ||
var GotState = false; | ||
TestUtils.RunAsync(() => TaskEx.Run(() => true).ContinueWith((task, state) => GotState = (bool)state, true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same deal, testing the Func<Task<bool>, object, bool>
overload instead of the Action<Task<bool>, object>
overload.
(5 places)
Fixed tests using the wrong overloads
Codecov Report
@@ Coverage Diff @@
## master #16 +/- ##
=========================================
+ Coverage 58.78% 63.4% +4.61%
=========================================
Files 17 17
Lines 461 511 +50
Branches 60 64 +4
=========================================
+ Hits 271 324 +53
+ Misses 166 163 -3
Partials 24 24
Continue to review full report at Codecov.
|
I think I did the rebase correctly...? It seems to have code coverage now. That should have fixed the tests. |
@AlphaGremlin Awesome! All the code looks ready! A quick explanatory detour next, for which I apologize! ℹ You did a merge, which is different than a rebase. A merge is when you join back together at the end with a merge commit that has two parent comments. A rebase is when you rewrite your commits to change your first commit's parent commit. GitHub reviews just happen to not work very well when you merge the master branch into your topic branch (PR branch). It counts all these changes from master as part of your diff, so it's hard to tell what you wrote versus what you pulled in from master. There's also a superfluous merge commit at the end: This explains why Codecov is still complaining that it can't find coverage for the master commit you're based off of, 6cb68ef. With a rebase, your first commit's parent would be d5ff32a instead (the current tip of master). ➡ Don't worry about rebasing in this PR. I can see that your changes have 100% coverage and I'd like to merge them. ⚠ I'd prefer to undo the merge with master first, though, so the diff in this PR is usable for anyone that looks back at it. Sorry about that! It's super easy though:
You've been really great and put up with a lot through this whole process and I appreciate that very much! I can't wait to get this in. 👍 |
Done :) |
🎉 Your tireless work is much appreciated! Thank you! |
Add ContinueWith overloads with the state parameter.
Found a few more that I'd missed in the previous PR, so I've added those.
Also, I've switched to handling the state value manually, because the compiler was creating 20 separate copies of exactly the same underlying class.