Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Update System.Threading.Tasks.Task for NET4.5/4.6 #296

Merged
merged 5 commits into from
Jan 26, 2016

Conversation

yaakov-h
Copy link
Contributor

@yaakov-h yaakov-h commented Nov 8, 2015

Adds missing .NET 4.5 API Task.FromResult<TResult>, and adds
new .NET 4.6 APIs FromCanceled, FromCanceled<TResult>, FromException,
FromException<TResult> and CompletedTask.
@yaakov-h
Copy link
Contributor Author

Any other suggestions?

@yaakov-h
Copy link
Contributor Author

Getting this error now when running buildCC.bat, but no idea why:

Build FAILED.

"C:\Workspace\Git\CodeContracts\Microsoft.Research\ManagedContract.Setup\buildMSI10.xml" (All target) (1) ->
"C:\Workspace\Git\CodeContracts\CodeContracts.sln" (Clean;Rebuild target) (2) ->
"C:\Workspace\Git\CodeContracts\Microsoft.Research\Contracts\MsCorlib\MsCorlib.Contracts10.csproj.metaproj" (Rebuild ta
rget) (41:3) ->
"C:\Workspace\Git\CodeContracts\Microsoft.Research\Contracts\MsCorlib\MsCorlib.Contracts10.csproj" (Rebuild target) (42
:3) ->
(BuildMultiTargets target) ->
  System.Threading.Tasks.Task.cs(1567,57): error CS1061: 'System.Threading.Tasks.Task<TResult>' does not contain a defi
nition for 'Exception' and no extension method 'Exception' accepting a first argument of type 'System.Threading.Tasks.T
ask<TResult>' could be found (are you missing a using directive or an assembly reference?) [C:\Workspace\Git\CodeContra
cts\Microsoft.Research\Contracts\MsCorlib\MsCorlib.Contracts10.csproj]
  System.Threading.Tasks.Task.cs(1568,58): error CS1061: 'System.Threading.Tasks.Task<TResult>' does not contain a defi
nition for 'IsCanceled' and no extension method 'IsCanceled' accepting a first argument of type 'System.Threading.Tasks
.Task<TResult>' could be found (are you missing a using directive or an assembly reference?) [C:\Workspace\Git\CodeCont
racts\Microsoft.Research\Contracts\MsCorlib\MsCorlib.Contracts10.csproj]
  System.Threading.Tasks.Task.cs(1569,57): error CS1061: 'System.Threading.Tasks.Task<TResult>' does not contain a defi
nition for 'IsCompleted' and no extension method 'IsCompleted' accepting a first argument of type 'System.Threading.Tas
ks.Task<TResult>' could be found (are you missing a using directive or an assembly reference?) [C:\Workspace\Git\CodeCo
ntracts\Microsoft.Research\Contracts\MsCorlib\MsCorlib.Contracts10.csproj]
  System.Threading.Tasks.Task.cs(1570,58): error CS1061: 'System.Threading.Tasks.Task<TResult>' does not contain a defi
nition for 'IsFaulted' and no extension method 'IsFaulted' accepting a first argument of type 'System.Threading.Tasks.T
ask<TResult>' could be found (are you missing a using directive or an assembly reference?) [C:\Workspace\Git\CodeContra
cts\Microsoft.Research\Contracts\MsCorlib\MsCorlib.Contracts10.csproj]
  System.Threading.Tasks.Task.cs(1571,57): error CS1061: 'System.Threading.Tasks.Task<TResult>' does not contain a defi
nition for 'Status' and no extension method 'Status' accepting a first argument of type 'System.Threading.Tasks.Task<TR
esult>' could be found (are you missing a using directive or an assembly reference?) [C:\Workspace\Git\CodeContracts\Mi
crosoft.Research\Contracts\MsCorlib\MsCorlib.Contracts10.csproj]
  System.Threading.Tasks.Task.cs(1571,67): error CS0103: The name 'TaskStatus' does not exist in the current context [C
:\Workspace\Git\CodeContracts\Microsoft.Research\Contracts\MsCorlib\MsCorlib.Contracts10.csproj]
  System.Threading.Tasks.Task.cs(1572,57): error CS1061: 'System.Threading.Tasks.Task<TResult>' does not contain a defi
nition for 'Result' and no extension method 'Result' accepting a first argument of type 'System.Threading.Tasks.Task<TR
esult>' could be found (are you missing a using directive or an assembly reference?) [C:\Workspace\Git\CodeContracts\Mi
crosoft.Research\Contracts\MsCorlib\MsCorlib.Contracts10.csproj]

    0 Warning(s)
    7 Error(s)

Time Elapsed 00:00:36.03
.
****************************************************
Build FAILED
****************************************************

Do I need to define those properties and the enum in the Contracts project?

@fedotovalex
Copy link
Contributor

Do I need to define those properties and the enum in the Contracts project?

Yes, you need to uncomment these properties in the Task class. I see the properties are there, but they were commented out, probably they did not seem relevant for the contracts assembly before (but now they are).

You will also need to add the TaskStatus enum.

@yaakov-h
Copy link
Contributor Author

OK, seems to be compiling now. Thanks for the pointers, @fedotovalex.

@yaakov-h
Copy link
Contributor Author

I should probably add actual contracts for AggregateException, but I'll do that as a separate PR after this.

Contract.Ensures(!Contract.Result<Task<TResult>>().IsCanceled);
Contract.Ensures(Contract.Result<Task<TResult>>().IsCompleted);
Contract.Ensures(!Contract.Result<Task<TResult>>().IsFaulted);
Contract.Ensures(Contract.Result<Task<TResult>>().Status == TaskStatus.RanToCompletion);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious would it be enough to leave just one postcondition that Status == TaskStatus.RanToCompletion and than express (via postconditions) relationship between Status and IsCanceled, IsCompleted and IsFaulted?

I'm fine with this approach but proposed one could be slightly easier to read, because all those postconditions:

+      Contract.Ensures(Contract.Result<Task<TResult>>().Exception == null);
 +      Contract.Ensures(!Contract.Result<Task<TResult>>().IsCanceled);
 +      Contract.Ensures(Contract.Result<Task<TResult>>().IsCompleted);
 +      Contract.Ensures(!Contract.Result<Task<TResult>>().IsFaulted);

Are just redundant.

@SergeyTeplyakov
Copy link
Contributor

Add some minor comments, but everything is LGTM.

@yaakov-h
Copy link
Contributor Author

Thanks. I'll take a shot at addressing your comments early next week.

Contract.Ensures(Contract.Result<Task>().IsCompleted);
Contract.Ensures(!Contract.Result<Task>().IsFaulted);
Contract.Ensures(Contract.Result<Task>().Status == TaskStatus.Canceled);
Contract.EnsuresOnThrow<ArgumentOutOfRangeException>(true, "Cancellation has not been requested for cancellationToken; its IsCancellationRequested property is false.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this kinds of contracts? It never fails at runtime and it seems that it has no value for static analyzer. Is it some kind of documentation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it actually does help static analyzer. Imagine you have a method

public void HandleCompletedTask(Task task)
{
    Contract.Requires(task.IsCompleted);
    ...
}

With the contracts above, you should be able to write

   HandleCompletedTask(Task.FromCanceled(cancellationToken));

and the static checker would not complain. Without the contract, you'll have to add an explicit Assume to keep the static checker quiet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought @hubuk's comment was specifically on the EnsuresOnThrow, in which case I have no idea what it's for, but I've added it purely to be consistent with existing contracts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, my question was about

Contract.EnsuresOnThrow<ArgumentOutOfRangeException>(true, "Cancellation has not been requested for cancellationToken; its IsCancellationRequested property is false.");

Never saw contracts like this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are quite a handful already.

SergeyTeplyakov added a commit that referenced this pull request Jan 26, 2016
Update System.Threading.Tasks.Task for NET4.5/4.6
@SergeyTeplyakov SergeyTeplyakov merged commit 1064c75 into microsoft:master Jan 26, 2016
@SergeyTeplyakov
Copy link
Contributor

@yaakov-h This PR broke the build. I'm going to revert it to fix the master.

@hubuk
Copy link
Contributor

hubuk commented Jan 26, 2016

@SergeyTeplyakov It seems as this is not the only one PR that required fixing. There are other problems related to enabling contracts for .Net 4.6. Looking into it right now.
BTW. f0c4d1a already contains fix for this part of problem caused by this PR.

@yaakov-h
Copy link
Contributor Author

Odd, the build appeared to work... I'd guess it's because I only tested this building on top of master, not on top of #291 (I think? Hard to remember) so NETFRAMEWORK_4_6 was never actually defined. Whoops!

@yaakov-h yaakov-h deleted the pr-Net46Task branch April 24, 2018 13:41
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants