You've already forked linux-packaging-mono
Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
parent
1190d13a04
commit
6bdd276d05
101
external/corefx/src/System.Threading.Tasks/System.Threading.Tasks.sln
vendored
Normal file
101
external/corefx/src/System.Threading.Tasks/System.Threading.Tasks.sln
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.22823.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Tasks.Tests", "tests\System.Threading.Tasks.Tests.csproj", "{B6C09633-D161-499A-8FE1-46B2D53A16E7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA} = {3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Tasks", "src\System.Threading.Tasks.csproj", "{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU = DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU
|
||||
ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU = ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU
|
||||
DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU = DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU
|
||||
ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU = ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU
|
||||
DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
|
||||
ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
|
||||
DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
|
||||
ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU = ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU
|
||||
DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU = DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU
|
||||
ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU = ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU
|
||||
DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU = DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU
|
||||
ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU = ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU
|
||||
DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU = DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU
|
||||
ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU = ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU
|
||||
DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU = DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU
|
||||
ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU = ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{B6C09633-D161-499A-8FE1-46B2D53A16E7}.ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = uap101aot-Windows_NT-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.Build.0 = uap101aot-Windows_NT-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = uap101aot-Windows_NT-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.Build.0 = uap101aot-Windows_NT-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = uap101aot-Windows_NT-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.Build.0 = uap101aot-Windows_NT-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = uap101aot-Windows_NT-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppuap101aot-Windows_NTnetcoreapp|AnyCPU.Build.0 = uap101aot-Windows_NT-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.ActiveCfg = net463-Windows_NT-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnet463-Windows_NTnetcoreapp|AnyCPU.Build.0 = net463-Windows_NT-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.ActiveCfg = netcoreapp1.2corert-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.Build.0 = netcoreapp1.2corert-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.ActiveCfg = netcoreapp1.2corert-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.Build.0 = netcoreapp1.2corert-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.ActiveCfg = netcoreapp1.2corert-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.DebugNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.Build.0 = netcoreapp1.2corert-Debug|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.ActiveCfg = netcoreapp1.2corert-Release|Any CPU
|
||||
{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}.ReleaseNETCoreAppnetcoreapp1.2corertnetcoreapp|AnyCPU.Build.0 = netcoreapp1.2corert-Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
8
external/corefx/src/System.Threading.Tasks/dir.props
vendored
Normal file
8
external/corefx/src/System.Threading.Tasks/dir.props
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\dir.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>4.1.0.0</AssemblyVersion>
|
||||
<IsNETCoreApp>true</IsNETCoreApp>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
9
external/corefx/src/System.Threading.Tasks/ref/Configurations.props
vendored
Normal file
9
external/corefx/src/System.Threading.Tasks/ref/Configurations.props
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netcoreapp;
|
||||
uap;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
157
external/corefx/src/System.Threading.Tasks/ref/System.Threading.Tasks.cs
vendored
Normal file
157
external/corefx/src/System.Threading.Tasks/ref/System.Threading.Tasks.cs
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
// ------------------------------------------------------------------------------
|
||||
// Changes to this file must follow the http://aka.ms/api-review process.
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
// These types were moved down to System.Runtime
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.AggregateException))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.ConfiguredTaskAwaitable))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.ICriticalNotifyCompletion))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.INotifyCompletion))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.TaskAwaiter))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.TaskAwaiter<>))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.YieldAwaitable))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.CancellationToken))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.CancellationTokenRegistration))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.Task))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.Task<>))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.TaskContinuationOptions))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.TaskCreationOptions))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.TaskFactory))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.TaskFactory<>))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.TaskScheduler))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.TaskStatus))]
|
||||
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Threading.Tasks.UnobservedTaskExceptionEventArgs))]
|
||||
|
||||
namespace System
|
||||
{
|
||||
public partial class OperationCanceledException : System.SystemException
|
||||
{
|
||||
public OperationCanceledException() { }
|
||||
public OperationCanceledException(string message) { }
|
||||
public OperationCanceledException(string message, System.Exception innerException) { }
|
||||
public OperationCanceledException(string message, System.Exception innerException, System.Threading.CancellationToken token) { }
|
||||
public OperationCanceledException(string message, System.Threading.CancellationToken token) { }
|
||||
public OperationCanceledException(System.Threading.CancellationToken token) { }
|
||||
protected OperationCanceledException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
|
||||
public System.Threading.CancellationToken CancellationToken { get { throw null; } }
|
||||
}
|
||||
}
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public partial struct AsyncTaskMethodBuilder
|
||||
{
|
||||
public System.Threading.Tasks.Task Task { get { throw null; } }
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.INotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
|
||||
public static System.Runtime.CompilerServices.AsyncTaskMethodBuilder Create() { throw null; }
|
||||
public void SetException(System.Exception exception) { }
|
||||
public void SetResult() { }
|
||||
public void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) { }
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
|
||||
}
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public partial struct AsyncTaskMethodBuilder<TResult>
|
||||
{
|
||||
public System.Threading.Tasks.Task<TResult> Task { get { throw null; } }
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.INotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
|
||||
public static System.Runtime.CompilerServices.AsyncTaskMethodBuilder<TResult> Create() { throw null; }
|
||||
public void SetException(System.Exception exception) { }
|
||||
public void SetResult(TResult result) { }
|
||||
public void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) { }
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
|
||||
}
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public partial struct AsyncVoidMethodBuilder
|
||||
{
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.INotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
|
||||
public static System.Runtime.CompilerServices.AsyncVoidMethodBuilder Create() { throw null; }
|
||||
public void SetException(System.Exception exception) { }
|
||||
public void SetResult() { }
|
||||
public void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) { }
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
|
||||
}
|
||||
public partial interface IAsyncStateMachine
|
||||
{
|
||||
void MoveNext();
|
||||
void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine stateMachine);
|
||||
}
|
||||
}
|
||||
namespace System.Threading
|
||||
{
|
||||
public partial class CancellationTokenSource : System.IDisposable
|
||||
{
|
||||
public CancellationTokenSource() { }
|
||||
public CancellationTokenSource(int millisecondsDelay) { }
|
||||
public CancellationTokenSource(System.TimeSpan delay) { }
|
||||
public bool IsCancellationRequested { get { throw null; } }
|
||||
public System.Threading.CancellationToken Token { get { throw null; } }
|
||||
public void Cancel() { }
|
||||
public void Cancel(bool throwOnFirstException) { }
|
||||
public void CancelAfter(int millisecondsDelay) { }
|
||||
public void CancelAfter(System.TimeSpan delay) { }
|
||||
public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(System.Threading.CancellationToken token1, System.Threading.CancellationToken token2) { throw null; }
|
||||
public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(params System.Threading.CancellationToken[] tokens) { throw null; }
|
||||
public void Dispose() { }
|
||||
protected virtual void Dispose(bool disposing) { }
|
||||
}
|
||||
}
|
||||
namespace System.Threading.Tasks
|
||||
{
|
||||
public partial class ConcurrentExclusiveSchedulerPair
|
||||
{
|
||||
public ConcurrentExclusiveSchedulerPair() { }
|
||||
public ConcurrentExclusiveSchedulerPair(System.Threading.Tasks.TaskScheduler taskScheduler) { }
|
||||
public ConcurrentExclusiveSchedulerPair(System.Threading.Tasks.TaskScheduler taskScheduler, int maxConcurrencyLevel) { }
|
||||
public ConcurrentExclusiveSchedulerPair(System.Threading.Tasks.TaskScheduler taskScheduler, int maxConcurrencyLevel, int maxItemsPerTask) { }
|
||||
public System.Threading.Tasks.Task Completion { get { throw null; } }
|
||||
public System.Threading.Tasks.TaskScheduler ConcurrentScheduler { get { throw null; } }
|
||||
public System.Threading.Tasks.TaskScheduler ExclusiveScheduler { get { throw null; } }
|
||||
public void Complete() { }
|
||||
}
|
||||
public partial class TaskCanceledException : System.OperationCanceledException
|
||||
{
|
||||
public TaskCanceledException() { }
|
||||
public TaskCanceledException(string message) { }
|
||||
public TaskCanceledException(string message, System.Exception innerException) { }
|
||||
public TaskCanceledException(System.Threading.Tasks.Task task) { }
|
||||
protected TaskCanceledException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
|
||||
public System.Threading.Tasks.Task Task { get { throw null; } }
|
||||
}
|
||||
public partial class TaskCompletionSource<TResult>
|
||||
{
|
||||
public TaskCompletionSource() { }
|
||||
public TaskCompletionSource(object state) { }
|
||||
public TaskCompletionSource(object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { }
|
||||
public TaskCompletionSource(System.Threading.Tasks.TaskCreationOptions creationOptions) { }
|
||||
public System.Threading.Tasks.Task<TResult> Task { get { throw null; } }
|
||||
public void SetCanceled() { }
|
||||
public void SetException(System.Collections.Generic.IEnumerable<System.Exception> exceptions) { }
|
||||
public void SetException(System.Exception exception) { }
|
||||
public void SetResult(TResult result) { }
|
||||
public bool TrySetCanceled() { throw null; }
|
||||
public bool TrySetCanceled(System.Threading.CancellationToken cancellationToken) { throw null; }
|
||||
public bool TrySetException(System.Collections.Generic.IEnumerable<System.Exception> exceptions) { throw null; }
|
||||
public bool TrySetException(System.Exception exception) { throw null; }
|
||||
public bool TrySetResult(TResult result) { throw null; }
|
||||
}
|
||||
public static partial class TaskExtensions
|
||||
{
|
||||
public static System.Threading.Tasks.Task Unwrap(this System.Threading.Tasks.Task<System.Threading.Tasks.Task> task) { throw null; }
|
||||
public static System.Threading.Tasks.Task<TResult> Unwrap<TResult>(this System.Threading.Tasks.Task<System.Threading.Tasks.Task<TResult>> task) { throw null; }
|
||||
}
|
||||
public partial class TaskSchedulerException : System.Exception
|
||||
{
|
||||
public TaskSchedulerException() { }
|
||||
public TaskSchedulerException(System.Exception innerException) { }
|
||||
public TaskSchedulerException(string message) { }
|
||||
public TaskSchedulerException(string message, System.Exception innerException) { }
|
||||
protected TaskSchedulerException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
|
||||
}
|
||||
}
|
||||
15
external/corefx/src/System.Threading.Tasks/ref/System.Threading.Tasks.csproj
vendored
Normal file
15
external/corefx/src/System.Threading.Tasks/ref/System.Threading.Tasks.csproj
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Release|AnyCPU'" />
|
||||
<ItemGroup>
|
||||
<Compile Include="System.Threading.Tasks.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
11
external/corefx/src/System.Threading.Tasks/src/ApiCompatBaseline.netcoreapp1.2corert.txt
vendored
Normal file
11
external/corefx/src/System.Threading.Tasks/src/ApiCompatBaseline.netcoreapp1.2corert.txt
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
Compat issues with assembly System.Threading.Tasks:
|
||||
CannotRemoveBaseTypeOrInterface : Type 'System.OperationCanceledException' does not inherit from base type 'System.SystemException' in the implementation but it does in the contract.
|
||||
MembersMustExist : Member 'System.OperationCanceledException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
|
||||
CannotRemoveBaseTypeOrInterface : Type 'System.Threading.Tasks.Task' does not implement interface 'System.IDisposable' in the implementation but it does in the contract.
|
||||
MembersMustExist : Member 'System.Threading.Tasks.Task.Dispose()' does not exist in the implementation but it does exist in the contract.
|
||||
MembersMustExist : Member 'System.Threading.Tasks.Task.Dispose(System.Boolean)' does not exist in the implementation but it does exist in the contract.
|
||||
CannotRemoveBaseTypeOrInterface : Type 'System.Threading.Tasks.Task<TResult>' does not implement interface 'System.IDisposable' in the implementation but it does in the contract.
|
||||
CannotRemoveBaseTypeOrInterface : Type 'System.Threading.Tasks.TaskCanceledException' does not inherit from base type 'System.SystemException' in the implementation but it does in the contract.
|
||||
MembersMustExist : Member 'System.Threading.Tasks.TaskCanceledException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
|
||||
MembersMustExist : Member 'System.Threading.Tasks.TaskSchedulerException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
|
||||
Total Issues: 9
|
||||
12
external/corefx/src/System.Threading.Tasks/src/ApiCompatBaseline.uap101aot.txt
vendored
Normal file
12
external/corefx/src/System.Threading.Tasks/src/ApiCompatBaseline.uap101aot.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Compat issues with assembly System.Threading.Tasks:
|
||||
MembersMustExist : Member 'System.AggregateException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
|
||||
CannotRemoveBaseTypeOrInterface : Type 'System.OperationCanceledException' does not inherit from base type 'System.SystemException' in the implementation but it does in the contract.
|
||||
MembersMustExist : Member 'System.OperationCanceledException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
|
||||
CannotRemoveBaseTypeOrInterface : Type 'System.Threading.Tasks.Task' does not implement interface 'System.IDisposable' in the implementation but it does in the contract.
|
||||
MembersMustExist : Member 'System.Threading.Tasks.Task.Dispose()' does not exist in the implementation but it does exist in the contract.
|
||||
MembersMustExist : Member 'System.Threading.Tasks.Task.Dispose(System.Boolean)' does not exist in the implementation but it does exist in the contract.
|
||||
CannotRemoveBaseTypeOrInterface : Type 'System.Threading.Tasks.Task<TResult>' does not implement interface 'System.IDisposable' in the implementation but it does in the contract.
|
||||
CannotRemoveBaseTypeOrInterface : Type 'System.Threading.Tasks.TaskCanceledException' does not inherit from base type 'System.SystemException' in the implementation but it does in the contract.
|
||||
MembersMustExist : Member 'System.Threading.Tasks.TaskCanceledException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
|
||||
MembersMustExist : Member 'System.Threading.Tasks.TaskSchedulerException..ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' does not exist in the implementation but it does exist in the contract.
|
||||
Total Issues: 10
|
||||
12
external/corefx/src/System.Threading.Tasks/src/Configurations.props
vendored
Normal file
12
external/corefx/src/System.Threading.Tasks/src/Configurations.props
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
uap101aot-Windows_NT;
|
||||
net463-Windows_NT;
|
||||
netcoreapp-Windows_NT;
|
||||
netcoreapp-Unix;
|
||||
netcoreapp1.2corert;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
37
external/corefx/src/System.Threading.Tasks/src/System.Threading.Tasks.csproj
vendored
Normal file
37
external/corefx/src/System.Threading.Tasks/src/System.Threading.Tasks.csproj
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{3BCAEAA6-3A29-49EC-B334-6E7BE8BE9ABA}</ProjectGuid>
|
||||
<AssemblyName>System.Threading.Tasks</AssemblyName>
|
||||
<IsPartialFacadeAssembly>true</IsPartialFacadeAssembly>
|
||||
</PropertyGroup>
|
||||
<!-- Default configurations to help VS understand the configurations -->
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net463-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net463-Windows_NT-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Unix-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Unix-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp1.2corert-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp1.2corert-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101aot-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap101aot-Windows_NT-Release|AnyCPU'" />
|
||||
<ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'">
|
||||
<Compile Include="System\Threading\Tasks\TaskExtensions.CoreCLR.cs" />
|
||||
<ProjectReference Include="..\..\System.Diagnostics.Debug\src\System.Diagnostics.Debug.csproj" />
|
||||
<TargetingPackReference Include="System.Private.CoreLib" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetGroup)' == 'net463'">
|
||||
<TargetingPackReference Include="mscorlib" />
|
||||
<TargetingPackReference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetGroup)' == 'uap101aot' or '$(TargetGroup)' == 'netcoreapp1.2corert'">
|
||||
<Compile Include="System\Threading\Tasks\TaskExtensions.CoreRT.cs" />
|
||||
<TargetingPackReference Include="System.Private.CoreLib" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ReferenceFromRuntime Include="System.Private.CoreLib" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
229
external/corefx/src/System.Threading.Tasks/src/System/Threading/Tasks/TaskExtensions.CoreCLR.cs
vendored
Normal file
229
external/corefx/src/System.Threading.Tasks/src/System/Threading/Tasks/TaskExtensions.CoreCLR.cs
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Threading.Tasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a set of static (Shared in Visual Basic) methods for working with specific kinds of
|
||||
/// <see cref="System.Threading.Tasks.Task"/> instances.
|
||||
/// </summary>
|
||||
public static class TaskExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a proxy <see cref="System.Threading.Tasks.Task">Task</see> that represents the
|
||||
/// asynchronous operation of a Task{Task}.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is often useful to be able to return a Task from a <see cref="System.Threading.Tasks.Task{TResult}">
|
||||
/// Task{TResult}</see>, where the inner Task represents work done as part of the outer Task{TResult}. However,
|
||||
/// doing so results in a Task{Task}, which, if not dealt with carefully, could produce unexpected behavior. Unwrap
|
||||
/// solves this problem by creating a proxy Task that represents the entire asynchronous operation of such a Task{Task}.
|
||||
/// </remarks>
|
||||
/// <param name="task">The Task{Task} to unwrap.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The exception that is thrown if the
|
||||
/// <paramref name="task"/> argument is null.</exception>
|
||||
/// <returns>A Task that represents the asynchronous operation of the provided Task{Task}.</returns>
|
||||
public static Task Unwrap(this Task<Task> task)
|
||||
{
|
||||
if (task == null)
|
||||
throw new ArgumentNullException(nameof(task));
|
||||
|
||||
// Fast path for an already successfully completed outer task: just return the inner one.
|
||||
// As in the subsequent slower path, a null inner task is special-cased to mean cancellation.
|
||||
if (task.Status == TaskStatus.RanToCompletion && (task.CreationOptions & TaskCreationOptions.AttachedToParent) == 0)
|
||||
{
|
||||
return task.Result ?? Task.FromCanceled(new CancellationToken(true));
|
||||
}
|
||||
|
||||
// Create a new Task to serve as a proxy for the actual inner task. Attach it
|
||||
// to the parent if the original was attached to the parent.
|
||||
var tcs = new TaskCompletionSource<VoidResult>(task.CreationOptions & TaskCreationOptions.AttachedToParent);
|
||||
TransferAsynchronously(tcs, task);
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a proxy <see cref="System.Threading.Tasks.Task{TResult}">Task{TResult}</see> that represents the
|
||||
/// asynchronous operation of a Task{Task{TResult}}.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is often useful to be able to return a Task{TResult} from a Task{TResult}, where the inner Task{TResult}
|
||||
/// represents work done as part of the outer Task{TResult}. However, doing so results in a Task{Task{TResult}},
|
||||
/// which, if not dealt with carefully, could produce unexpected behavior. Unwrap solves this problem by
|
||||
/// creating a proxy Task{TResult} that represents the entire asynchronous operation of such a Task{Task{TResult}}.
|
||||
/// </remarks>
|
||||
/// <param name="task">The Task{Task{TResult}} to unwrap.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The exception that is thrown if the
|
||||
/// <paramref name="task"/> argument is null.</exception>
|
||||
/// <returns>A Task{TResult} that represents the asynchronous operation of the provided Task{Task{TResult}}.</returns>
|
||||
public static Task<TResult> Unwrap<TResult>(this Task<Task<TResult>> task)
|
||||
{
|
||||
if (task == null)
|
||||
throw new ArgumentNullException(nameof(task));
|
||||
|
||||
// Fast path for an already successfully completed outer task: just return the inner one.
|
||||
// As in the subsequent slower path, a null inner task is special-cased to mean cancellation.
|
||||
if (task.Status == TaskStatus.RanToCompletion && (task.CreationOptions & TaskCreationOptions.AttachedToParent) == 0)
|
||||
{
|
||||
return task.Result ?? Task.FromCanceled<TResult>(new CancellationToken(true));
|
||||
}
|
||||
|
||||
// Create a new Task to serve as a proxy for the actual inner task. Attach it
|
||||
// to the parent if the original was attached to the parent.
|
||||
var tcs = new TaskCompletionSource<TResult>(task.CreationOptions & TaskCreationOptions.AttachedToParent);
|
||||
TransferAsynchronously(tcs, task);
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transfer the results of the <paramref name="outer"/> task's inner task to the <paramref name="completionSource"/>.
|
||||
/// </summary>
|
||||
/// <param name="completionSource">The completion source to which results should be transfered.</param>
|
||||
/// <param name="outer">
|
||||
/// The outer task that when completed will yield an inner task whose results we want marshaled to the <paramref name="completionSource"/>.
|
||||
/// </param>
|
||||
private static void TransferAsynchronously<TResult, TInner>(TaskCompletionSource<TResult> completionSource, Task<TInner> outer) where TInner : Task
|
||||
{
|
||||
Action callback = null;
|
||||
|
||||
// Create a continuation delegate. For performance reasons, we reuse the same delegate/closure across multiple
|
||||
// continuations; by using .ConfigureAwait(false).GetAwaiter().UnsafeOnComplete(action), in most cases
|
||||
// this delegate can be stored directly into the Task's continuation field, eliminating the need for additional
|
||||
// allocations. Thus, this whole Unwrap operation generally results in four allocations: one for the TaskCompletionSource,
|
||||
// one for the returned task, one for the delegate, and one for the closure. Since the delegate is used
|
||||
// across multiple continuations, we use the callback variable as well to indicate which continuation we're in:
|
||||
// if the callback is non-null, then we're processing the continuation for the outer task and use the callback
|
||||
// object as the continuation off of the inner task; if the callback is null, then we're processing the
|
||||
// inner task.
|
||||
callback = delegate
|
||||
{
|
||||
Debug.Assert(outer.IsCompleted);
|
||||
if (callback != null)
|
||||
{
|
||||
// Process the outer task's completion
|
||||
|
||||
// Clear out the callback field to indicate that any future invocations should
|
||||
// be for processing the inner task, but store away a local copy in case we need
|
||||
// to use it as the continuation off of the outer task.
|
||||
Action innerCallback = callback;
|
||||
callback = null;
|
||||
|
||||
bool result = true;
|
||||
switch (outer.Status)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
case TaskStatus.Faulted:
|
||||
// The outer task has completed as canceled or faulted; transfer that
|
||||
// status to the completion source, and we're done.
|
||||
result = completionSource.TrySetFromTask(outer);
|
||||
break;
|
||||
case TaskStatus.RanToCompletion:
|
||||
Task inner = outer.Result;
|
||||
if (inner == null)
|
||||
{
|
||||
// The outer task completed successfully, but with a null inner task;
|
||||
// cancel the completionSource, and we're done.
|
||||
result = completionSource.TrySetCanceled();
|
||||
}
|
||||
else if (inner.IsCompleted)
|
||||
{
|
||||
// The inner task also completed! Transfer the results, and we're done.
|
||||
result = completionSource.TrySetFromTask(inner);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run this delegate again once the inner task has completed.
|
||||
inner.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(innerCallback);
|
||||
}
|
||||
break;
|
||||
}
|
||||
Debug.Assert(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Process the inner task's completion. All we need to do is transfer its results
|
||||
// to the completion source.
|
||||
Debug.Assert(outer.Status == TaskStatus.RanToCompletion);
|
||||
Debug.Assert(outer.Result.IsCompleted);
|
||||
completionSource.TrySetFromTask(outer.Result);
|
||||
}
|
||||
};
|
||||
|
||||
// Kick things off by hooking up the callback as the task's continuation
|
||||
outer.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(callback);
|
||||
}
|
||||
|
||||
/// <summary>Copies that ending state information from <paramref name="task"/> to <paramref name="completionSource"/>.</summary>
|
||||
private static bool TrySetFromTask<TResult>(this TaskCompletionSource<TResult> completionSource, Task task)
|
||||
{
|
||||
Debug.Assert(task.IsCompleted);
|
||||
|
||||
// Before transferring the results, check to make sure we're not too deep on the stack. Calling TrySet*
|
||||
// will cause any synchronous continuations to be invoked, which is fine unless we're so deep that doing
|
||||
// so overflows. ContinueWith has built-in support for avoiding such stack dives, but that support is not
|
||||
// (yet) part of await's infrastructure, so until it is we mimic it manually. This matches the behavior
|
||||
// employed by the Unwrap implementation in mscorlib.
|
||||
if (!RuntimeHelpers.TryEnsureSufficientExecutionStack())
|
||||
{
|
||||
// This is very rare. We're too deep to safely invoke
|
||||
// TrySet* synchronously, so do so asynchronously instead.
|
||||
Task.Factory.StartNew(s =>
|
||||
{
|
||||
var t = (Tuple<TaskCompletionSource<TResult>, Task>)s;
|
||||
TrySetFromTask(t.Item1, t.Item2);
|
||||
}, Tuple.Create(completionSource, task), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Transfer the results from the supplied Task to the TaskCompletionSource.
|
||||
bool result = false;
|
||||
switch(task.Status)
|
||||
{
|
||||
case TaskStatus.Canceled:
|
||||
result = completionSource.TrySetCanceled(ExtractCancellationToken(task));
|
||||
break;
|
||||
|
||||
case TaskStatus.Faulted:
|
||||
result = completionSource.TrySetException(task.Exception.InnerExceptions);
|
||||
break;
|
||||
|
||||
case TaskStatus.RanToCompletion:
|
||||
Task<TResult> resultTask = task as Task<TResult>;
|
||||
result = resultTask != null ?
|
||||
completionSource.TrySetResult(resultTask.Result) :
|
||||
completionSource.TrySetResult(default(TResult));
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Gets the CancellationToken associated with a canceled task.</summary>
|
||||
private static CancellationToken ExtractCancellationToken(Task task)
|
||||
{
|
||||
// With the public Task APIs as of .NET 4.6, the only way to extract a CancellationToken
|
||||
// that was associated with a Task is by await'ing it, catching the resulting
|
||||
// OperationCanceledException, and getting the token from the OCE.
|
||||
Debug.Assert(task.IsCanceled);
|
||||
try
|
||||
{
|
||||
task.GetAwaiter().GetResult();
|
||||
Debug.Fail("Waiting on the canceled task should always result in an OCE, even if it's manufactured at the time of the wait.");
|
||||
return new CancellationToken(true);
|
||||
}
|
||||
catch (OperationCanceledException oce)
|
||||
{
|
||||
// This token may not have cancellation requested; that's ok.
|
||||
// That can happen if, for example, the Task is canceled with
|
||||
// TaskCompletionSource<T>.SetCanceled(), without a token.
|
||||
return oce.CancellationToken;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Dummy type to use as a void TResult.</summary>
|
||||
private struct VoidResult { }
|
||||
}
|
||||
}
|
||||
72
external/corefx/src/System.Threading.Tasks/src/System/Threading/Tasks/TaskExtensions.CoreRT.cs
vendored
Normal file
72
external/corefx/src/System.Threading.Tasks/src/System/Threading/Tasks/TaskExtensions.CoreRT.cs
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace System.Threading.Tasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a set of static (Shared in Visual Basic) methods for working with specific kinds of
|
||||
/// <see cref="System.Threading.Tasks.Task"/> instances.
|
||||
/// </summary>
|
||||
public static class TaskExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a proxy <see cref="System.Threading.Tasks.Task">Task</see> that represents the
|
||||
/// asynchronous operation of a Task{Task}.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is often useful to be able to return a Task from a <see cref="System.Threading.Tasks.Task{TResult}">
|
||||
/// Task{TResult}</see>, where the inner Task represents work done as part of the outer Task{TResult}. However,
|
||||
/// doing so results in a Task{Task}, which, if not dealt with carefully, could produce unexpected behavior. Unwrap
|
||||
/// solves this problem by creating a proxy Task that represents the entire asynchronous operation of such a Task{Task}.
|
||||
/// </remarks>
|
||||
/// <param name="task">The Task{Task} to unwrap.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The exception that is thrown if the
|
||||
/// <paramref name="task"/> argument is null.</exception>
|
||||
/// <returns>A Task that represents the asynchronous operation of the provided Task{Task}.</returns>
|
||||
public static Task Unwrap(this Task<Task> task)
|
||||
{
|
||||
if (task == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(task));
|
||||
}
|
||||
|
||||
// Creates a proxy Task and hooks up the logic to have it represent the task.Result
|
||||
Task promise = Task.CreateUnwrapPromise<VoidResult>(task, lookForOce: false);
|
||||
|
||||
// Return the proxy immediately
|
||||
return promise;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a proxy <see cref="System.Threading.Tasks.Task{TResult}">Task{TResult}</see> that represents the
|
||||
/// asynchronous operation of a Task{Task{TResult}}.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is often useful to be able to return a Task{TResult} from a Task{TResult}, where the inner Task{TResult}
|
||||
/// represents work done as part of the outer Task{TResult}. However, doing so results in a Task{Task{TResult}},
|
||||
/// which, if not dealt with carefully, could produce unexpected behavior. Unwrap solves this problem by
|
||||
/// creating a proxy Task{TResult} that represents the entire asynchronous operation of such a Task{Task{TResult}}.
|
||||
/// </remarks>
|
||||
/// <param name="task">The Task{Task{TResult}} to unwrap.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">The exception that is thrown if the
|
||||
/// <paramref name="task"/> argument is null.</exception>
|
||||
/// <returns>A Task{TResult} that represents the asynchronous operation of the provided Task{Task{TResult}}.</returns>
|
||||
public static Task<TResult> Unwrap<TResult>(this Task<Task<TResult>> task)
|
||||
{
|
||||
if (task == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(task));
|
||||
}
|
||||
|
||||
// Creates a proxy Task<TResult> and hooks up the logic to have it represent the task.Result
|
||||
Task<TResult> promise = Task.CreateUnwrapPromise<TResult>(task, lookForOce: false);
|
||||
|
||||
// Return the proxy immediately
|
||||
return promise;
|
||||
}
|
||||
|
||||
// Used as a placeholder TResult to indicate that a Task<TResult> has a void TResult
|
||||
private struct VoidResult { }
|
||||
}
|
||||
}
|
||||
131
external/corefx/src/System.Threading.Tasks/tests/AggregateExceptionTests.cs
vendored
Normal file
131
external/corefx/src/System.Threading.Tasks/tests/AggregateExceptionTests.cs
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Xunit;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Threading.Tasks.Tests
|
||||
{
|
||||
public class AggregateExceptionTests
|
||||
{
|
||||
[Fact]
|
||||
public static void ConstructorBasic()
|
||||
{
|
||||
AggregateException ex = new AggregateException();
|
||||
Assert.Equal(ex.InnerExceptions.Count, 0);
|
||||
Assert.True(ex.Message != null, "RunAggregateException_Constructor: FAILED. Message property is null when the default constructor is used, expected a default message");
|
||||
|
||||
ex = new AggregateException("message");
|
||||
Assert.Equal(ex.InnerExceptions.Count, 0);
|
||||
Assert.True(ex.Message != null, "RunAggregateException_Constructor: FAILED. Message property is null when the default constructor(string) is used");
|
||||
|
||||
ex = new AggregateException("message", new Exception());
|
||||
Assert.Equal(ex.InnerExceptions.Count, 1);
|
||||
Assert.True(ex.Message != null, "RunAggregateException_Constructor: FAILED. Message property is null when the default constructor(string, Exception) is used");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void ConstructorInvalidArguments()
|
||||
{
|
||||
AggregateException ex = new AggregateException();
|
||||
Assert.Throws<ArgumentNullException>(
|
||||
() => ex = new AggregateException("message", (Exception)null));
|
||||
|
||||
Assert.Throws<ArgumentNullException>(
|
||||
() => ex = new AggregateException("message", (IEnumerable<Exception>)null));
|
||||
|
||||
Assert.Throws<ArgumentException>(
|
||||
() => ex = new AggregateException("message", new[] { new Exception(), null }));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void BaseExceptions()
|
||||
{
|
||||
AggregateException ex = new AggregateException();
|
||||
Assert.Equal(ex.GetBaseException(), ex);
|
||||
|
||||
Exception[] innerExceptions = new Exception[0];
|
||||
ex = new AggregateException(innerExceptions);
|
||||
Assert.Equal(ex.GetBaseException(), ex);
|
||||
|
||||
innerExceptions = new Exception[1] { new AggregateException() };
|
||||
ex = new AggregateException(innerExceptions);
|
||||
Assert.Equal(ex.GetBaseException(), innerExceptions[0]);
|
||||
|
||||
innerExceptions = new Exception[2] { new AggregateException(), new AggregateException() };
|
||||
ex = new AggregateException(innerExceptions);
|
||||
Assert.Equal(ex.GetBaseException(), ex);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void Handle()
|
||||
{
|
||||
AggregateException ex = new AggregateException();
|
||||
ex = new AggregateException(new[] { new ArgumentException(), new ArgumentException(), new ArgumentException() });
|
||||
int handledCount = 0;
|
||||
ex.Handle((e) =>
|
||||
{
|
||||
if (e is ArgumentException)
|
||||
{
|
||||
handledCount++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
Assert.Equal(handledCount, ex.InnerExceptions.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void HandleInvalidCases()
|
||||
{
|
||||
AggregateException ex = new AggregateException();
|
||||
Assert.Throws<ArgumentNullException>(() => ex.Handle(null));
|
||||
|
||||
ex = new AggregateException(new[] { new Exception(), new ArgumentException(), new ArgumentException() });
|
||||
int handledCount = 0;
|
||||
Assert.Throws<AggregateException>(
|
||||
() => ex.Handle((e) =>
|
||||
{
|
||||
if (e is ArgumentException)
|
||||
{
|
||||
handledCount++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
// Validates that flattening (including recursive) works.
|
||||
[Fact]
|
||||
public static void Flatten()
|
||||
{
|
||||
Exception exceptionA = new Exception("A");
|
||||
Exception exceptionB = new Exception("B");
|
||||
Exception exceptionC = new Exception("C");
|
||||
|
||||
AggregateException aggExceptionBase = new AggregateException(exceptionA, exceptionB, exceptionC);
|
||||
|
||||
// Verify flattening one with another.
|
||||
// > Flattening (no recursion)...
|
||||
|
||||
AggregateException flattened1 = aggExceptionBase.Flatten();
|
||||
Exception[] expected1 = new Exception[] {
|
||||
exceptionA, exceptionB, exceptionC
|
||||
};
|
||||
|
||||
Assert.Equal(expected1, flattened1.InnerExceptions);
|
||||
|
||||
// Verify flattening one with another, accounting for recursion.
|
||||
AggregateException aggExceptionRecurse = new AggregateException(aggExceptionBase, aggExceptionBase);
|
||||
AggregateException flattened2 = aggExceptionRecurse.Flatten();
|
||||
Exception[] expected2 = new Exception[] {
|
||||
exceptionA, exceptionB, exceptionC, exceptionA, exceptionB, exceptionC,
|
||||
};
|
||||
|
||||
Assert.Equal(expected2, flattened2.InnerExceptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
624
external/corefx/src/System.Threading.Tasks/tests/CESchedulerPairTests.cs
vendored
Normal file
624
external/corefx/src/System.Threading.Tasks/tests/CESchedulerPairTests.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1342
external/corefx/src/System.Threading.Tasks/tests/CancellationTokenTests.cs
vendored
Normal file
1342
external/corefx/src/System.Threading.Tasks/tests/CancellationTokenTests.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
external/corefx/src/System.Threading.Tasks/tests/Configurations.props
vendored
Normal file
9
external/corefx/src/System.Threading.Tasks/tests/Configurations.props
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netstandard1.5;
|
||||
netstandard;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
255
external/corefx/src/System.Threading.Tasks/tests/MethodCoverage.cs
vendored
Normal file
255
external/corefx/src/System.Threading.Tasks/tests/MethodCoverage.cs
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using Xunit;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TaskCoverage
|
||||
{
|
||||
public class Coverage
|
||||
{
|
||||
// Regression test: Validates that tasks can wait on int.MaxValue without assertion.
|
||||
[Fact]
|
||||
public static void TaskWait_MaxInt32()
|
||||
{
|
||||
Task t = Task.Delay(1);
|
||||
Debug.WriteLine("Wait with int.Maxvalue");
|
||||
Task.WaitAll(new Task[] { t }, int.MaxValue);
|
||||
}
|
||||
|
||||
//EH
|
||||
[Fact]
|
||||
[OuterLoop]
|
||||
public static void TaskContinuation()
|
||||
{
|
||||
int taskCount = Environment.ProcessorCount;
|
||||
int maxDOP = Int32.MaxValue;
|
||||
int maxNumberExecutionsPerTask = 1;
|
||||
int data = 0;
|
||||
|
||||
Task[] allTasks = new Task[taskCount + 1];
|
||||
|
||||
CancellationTokenSource[] cts = new CancellationTokenSource[taskCount + 1];
|
||||
for (int i = 0; i <= taskCount; i++)
|
||||
{
|
||||
cts[i] = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
CancellationTokenSource cts2 = new CancellationTokenSource();
|
||||
ConcurrentExclusiveSchedulerPair scheduler = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, maxDOP, maxNumberExecutionsPerTask);
|
||||
for (int i = 0; i <= taskCount; i++)
|
||||
{
|
||||
int j = i;
|
||||
allTasks[i] = new Task(() =>
|
||||
{
|
||||
new TaskFactory(TaskScheduler.Current).StartNew(() => { }).
|
||||
ContinueWith((task, o) =>
|
||||
{
|
||||
int d = (int)o;
|
||||
Interlocked.Add(ref data, d);
|
||||
}, j).
|
||||
ContinueWith((task, o) =>
|
||||
{
|
||||
int d = (int)o;
|
||||
Interlocked.Add(ref data, d);
|
||||
cts[d].Cancel();
|
||||
if (d <= taskCount)
|
||||
{
|
||||
throw new OperationCanceledException(cts[d].Token);
|
||||
}
|
||||
return "Done";
|
||||
}, j, cts[j].Token).
|
||||
ContinueWith((task, o) =>
|
||||
{
|
||||
int d = (int)o;
|
||||
Interlocked.Add(ref data, d);
|
||||
}, j, CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, TaskScheduler.Default).Wait(Int32.MaxValue - 1, cts2.Token);
|
||||
});
|
||||
|
||||
allTasks[i].Start(scheduler.ConcurrentScheduler);
|
||||
}
|
||||
|
||||
Task.WaitAll(allTasks, int.MaxValue - 1, CancellationToken.None);
|
||||
Debug.WriteLine("Tasks ended: result {0}", data);
|
||||
Task completion = scheduler.Completion;
|
||||
scheduler.Complete();
|
||||
completion.Wait();
|
||||
|
||||
int expectedResult = 3 * taskCount * (taskCount + 1) / 2;
|
||||
Assert.Equal(expectedResult, data);
|
||||
|
||||
Assert.NotEqual(TaskScheduler.Default.Id, scheduler.ConcurrentScheduler.Id);
|
||||
Assert.NotEqual(TaskScheduler.Default.Id, scheduler.ExclusiveScheduler.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test various Task.WhenAll and Wait overloads - EH
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public static void TaskWaitWithCTS()
|
||||
{
|
||||
ManualResetEvent mre = new ManualResetEvent(false);
|
||||
ManualResetEvent mreCont = new ManualResetEvent(false);
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
|
||||
int? taskId1 = 0; int? taskId2 = 0;
|
||||
int? taskId12 = 0; int? taskId22 = 0;
|
||||
|
||||
Task t1 = Task.Factory.StartNew(() => { mre.WaitOne(); taskId1 = Task.CurrentId; });
|
||||
Task t2 = Task.Factory.StartNew(() => { mre.WaitOne(); taskId2 = Task.CurrentId; cts.Cancel(); });
|
||||
|
||||
List<Task<int?>> whenAllTaskResult = new List<Task<int?>>();
|
||||
List<Task> whenAllTask = new List<Task>();
|
||||
whenAllTask.Add(t1); whenAllTask.Add(t2);
|
||||
Task<int> contTask = Task.WhenAll(whenAllTask).ContinueWith<int>(
|
||||
(task) =>
|
||||
{
|
||||
// when task1 ends, the token will be cancelled
|
||||
// move the continuation task in cancellation state
|
||||
if (cts.IsCancellationRequested) { throw new OperationCanceledException(cts.Token); }
|
||||
return 0;
|
||||
}, cts.Token);
|
||||
contTask.ContinueWith((task) => { mreCont.Set(); });
|
||||
|
||||
whenAllTaskResult.Add(Task<int?>.Factory.StartNew((o) => { mre.WaitOne((int)o); return Task.CurrentId; }, 10));
|
||||
whenAllTaskResult.Add(Task<int?>.Factory.StartNew((o) => { mre.WaitOne((int)o); return Task.CurrentId; }, 10));
|
||||
|
||||
t1.Wait(5, cts.Token);
|
||||
Task.WhenAll(whenAllTaskResult).ContinueWith((task) => { taskId12 = task.Result[0]; taskId22 = task.Result[1]; mre.Set(); });
|
||||
// Task 2 calls CancellationTokenSource.Cancel. Thus, expect and not fail for System.OperationCanceledException being thrown.
|
||||
try
|
||||
{
|
||||
t2.Wait(cts.Token);
|
||||
}
|
||||
catch (System.OperationCanceledException) { } // expected, do nothing
|
||||
|
||||
Assert.NotEqual<int?>(taskId1, taskId2);
|
||||
Assert.NotEqual<int?>(taskId12, taskId22);
|
||||
|
||||
Debug.WriteLine("Waiting on continuation task that should move into the cancelled state.");
|
||||
mreCont.WaitOne();
|
||||
Assert.True(contTask.Status == TaskStatus.Canceled, "Task status is not correct");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// test WaitAny and when Any overloads
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public static void TaskWaitAny_WhenAny()
|
||||
{
|
||||
ManualResetEvent mre = new ManualResetEvent(false);
|
||||
ManualResetEvent mre2 = new ManualResetEvent(false);
|
||||
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
|
||||
Task t1 = Task.Factory.StartNew(() => { mre.WaitOne(); });
|
||||
Task t2 = Task.Factory.StartNew(() => { mre.WaitOne(); });
|
||||
|
||||
Task<int?> t11 = Task.Factory.StartNew(() => { mre2.WaitOne(); return Task.CurrentId; });
|
||||
Task<int?> t21 = Task.Factory.StartNew(() => { mre2.WaitOne(); return Task.CurrentId; });
|
||||
|
||||
|
||||
//waitAny with token and timeout
|
||||
Task[] waitAny = new Task[] { t1, t2 };
|
||||
int timeout = Task.WaitAny(waitAny, 1, cts.Token);
|
||||
|
||||
//task whenany
|
||||
Task.Factory.StartNew(() => { Task.Delay(20); mre.Set(); });
|
||||
List<Task> whenAnyTask = new List<Task>(); whenAnyTask.Add(t1); whenAnyTask.Add(t2);
|
||||
List<Task<int?>> whenAnyTaskResult = new List<Task<int?>>(); whenAnyTaskResult.Add(t11); whenAnyTaskResult.Add(t21);
|
||||
|
||||
//task<tresult> whenany
|
||||
int? taskId = 0; //this will be set to the first task<int?> ID that ends
|
||||
Task waitOnIt = Task.WhenAny(whenAnyTaskResult).ContinueWith((task) => { taskId = task.Result.Result; });
|
||||
Task.WhenAny(whenAnyTask).ContinueWith((task) => { mre2.Set(); });
|
||||
|
||||
Debug.WriteLine("Wait on the scenario to finish");
|
||||
waitOnIt.Wait();
|
||||
Assert.Equal<int>(-1, timeout);
|
||||
Assert.Equal<int>(t11.Id, t11.Result.Value);
|
||||
Assert.Equal<int>(t21.Id, t21.Result.Value);
|
||||
|
||||
bool whenAnyVerification = taskId == t11.Id || taskId == t21.Id;
|
||||
|
||||
Assert.True(whenAnyVerification, string.Format("The id for whenAny is not correct expected to be {0} or {1} and it is {2}", t11.Id, t21.Id, taskId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void CancellationTokenRegitration()
|
||||
{
|
||||
ManualResetEvent mre = new ManualResetEvent(false);
|
||||
ManualResetEvent mre2 = new ManualResetEvent(false);
|
||||
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
cts.Token.Register((o) => { mre.Set(); }, 1, true);
|
||||
|
||||
cts.CancelAfter(5);
|
||||
Debug.WriteLine("Wait on the scenario to finish");
|
||||
mre.WaitOne();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// verify that the taskawaiter.UnsafeOnCompleted is invoked
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public static void TaskAwaiter()
|
||||
{
|
||||
ManualResetEvent mre = new ManualResetEvent(false);
|
||||
ManualResetEvent mre2 = new ManualResetEvent(false);
|
||||
ManualResetEvent mre3 = new ManualResetEvent(false);
|
||||
|
||||
Task t1 = Task.Factory.StartNew(() => { mre.WaitOne(); });
|
||||
Task<int> t11 = Task.Factory.StartNew(() => { mre.WaitOne(); return 1; });
|
||||
t1.GetAwaiter().UnsafeOnCompleted(() => { mre2.Set(); });
|
||||
t11.GetAwaiter().UnsafeOnCompleted(() => { mre3.Set(); });
|
||||
mre.Set();
|
||||
|
||||
Debug.WriteLine("Wait on the scenario to finish");
|
||||
mre2.WaitOne(); mre3.WaitOne();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// verify that the taskawaiter.UnsafeOnCompleted is invoked
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public static void TaskConfigurableAwaiter()
|
||||
{
|
||||
ManualResetEvent mre = new ManualResetEvent(false);
|
||||
ManualResetEvent mre2 = new ManualResetEvent(false);
|
||||
ManualResetEvent mre3 = new ManualResetEvent(false);
|
||||
|
||||
Task t1 = Task.Factory.StartNew(() => { mre.WaitOne(); });
|
||||
Task<int> t11 = Task.Factory.StartNew(() => { mre.WaitOne(); return 1; });
|
||||
t1.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(() => { mre2.Set(); });
|
||||
t11.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(() => { mre3.Set(); });
|
||||
mre.Set();
|
||||
|
||||
Debug.WriteLine("Wait on the scenario to finish");
|
||||
mre2.WaitOne(); mre3.WaitOne();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// FromAsync testing: Not supported in .NET Native
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public static void FromAsync()
|
||||
{
|
||||
Task emptyTask = new Task(() => { });
|
||||
ManualResetEvent mre1 = new ManualResetEvent(false);
|
||||
ManualResetEvent mre2 = new ManualResetEvent(false);
|
||||
|
||||
Task.Factory.FromAsync(emptyTask, (iar) => { mre1.Set(); }, TaskCreationOptions.None, TaskScheduler.Current);
|
||||
Task<int>.Factory.FromAsync(emptyTask, (iar) => { mre2.Set(); return 1; }, TaskCreationOptions.None, TaskScheduler.Current);
|
||||
emptyTask.Start();
|
||||
|
||||
Debug.WriteLine("Wait on the scenario to finish");
|
||||
mre1.WaitOne();
|
||||
mre2.WaitOne();
|
||||
}
|
||||
}
|
||||
}
|
||||
29
external/corefx/src/System.Threading.Tasks/tests/OperationCanceledExceptionTests.cs
vendored
Normal file
29
external/corefx/src/System.Threading.Tasks/tests/OperationCanceledExceptionTests.cs
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Xunit;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Threading.Tasks.Tests
|
||||
{
|
||||
public static class OperationCanceledExceptionTests
|
||||
{
|
||||
[Fact]
|
||||
public static void BasicConstructors()
|
||||
{
|
||||
CancellationToken ct1 = new CancellationTokenSource().Token;
|
||||
OperationCanceledException ex1 = new OperationCanceledException(ct1);
|
||||
Assert.Equal(ct1, ex1.CancellationToken);
|
||||
|
||||
CancellationToken ct2 = new CancellationTokenSource().Token;
|
||||
OperationCanceledException ex2 = new OperationCanceledException("message", ct2);
|
||||
Assert.Equal(ct2, ex2.CancellationToken);
|
||||
|
||||
CancellationToken ct3 = new CancellationTokenSource().Token;
|
||||
OperationCanceledException ex3 = new OperationCanceledException("message", new Exception("inner"), ct3);
|
||||
Assert.Equal(ct3, ex3.CancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
394
external/corefx/src/System.Threading.Tasks/tests/System.Runtime.CompilerServices/TaskAwaiterTests.cs
vendored
Normal file
394
external/corefx/src/System.Threading.Tasks/tests/System.Runtime.CompilerServices/TaskAwaiterTests.cs
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Xunit;
|
||||
|
||||
namespace System.Threading.Tasks.Tests
|
||||
{
|
||||
public class TaskAwaiterTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, null)]
|
||||
[InlineData(true, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, null)]
|
||||
public static void OnCompleted_CompletesInAnotherSynchronizationContext(bool generic, bool? continueOnCapturedContext)
|
||||
{
|
||||
SynchronizationContext origCtx = SynchronizationContext.Current;
|
||||
try
|
||||
{
|
||||
// Create a context that tracks operations, and set it as current
|
||||
var validateCtx = new ValidateCorrectContextSynchronizationContext();
|
||||
Assert.Equal(0, validateCtx.PostCount);
|
||||
SynchronizationContext.SetSynchronizationContext(validateCtx);
|
||||
|
||||
// Create a not-completed task and get an awaiter for it
|
||||
var mres = new ManualResetEventSlim();
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
|
||||
// Hook up a callback
|
||||
bool postedInContext = false;
|
||||
Action callback = () =>
|
||||
{
|
||||
postedInContext = ValidateCorrectContextSynchronizationContext.IsPostedInContext;
|
||||
mres.Set();
|
||||
};
|
||||
if (generic)
|
||||
{
|
||||
if (continueOnCapturedContext.HasValue) tcs.Task.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().OnCompleted(callback);
|
||||
else tcs.Task.GetAwaiter().OnCompleted(callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (continueOnCapturedContext.HasValue) ((Task)tcs.Task).ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().OnCompleted(callback);
|
||||
else ((Task)tcs.Task).GetAwaiter().OnCompleted(callback);
|
||||
}
|
||||
Assert.False(mres.IsSet, "Callback should not yet have run.");
|
||||
|
||||
// Complete the task in another context and wait for the callback to run
|
||||
Task.Run(() => tcs.SetResult(null));
|
||||
mres.Wait();
|
||||
|
||||
// Validate the callback ran and in the correct context
|
||||
bool shouldHavePosted = !continueOnCapturedContext.HasValue || continueOnCapturedContext.Value;
|
||||
Assert.Equal(shouldHavePosted ? 1 : 0, validateCtx.PostCount);
|
||||
Assert.Equal(shouldHavePosted, postedInContext);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Reset back to the original context
|
||||
SynchronizationContext.SetSynchronizationContext(origCtx);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, null)]
|
||||
[InlineData(true, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, null)]
|
||||
public static void OnCompleted_CompletesInAnotherTaskScheduler(bool generic, bool? continueOnCapturedContext)
|
||||
{
|
||||
SynchronizationContext origCtx = SynchronizationContext.Current;
|
||||
try
|
||||
{
|
||||
SynchronizationContext.SetSynchronizationContext(null); // get off xunit's SynchronizationContext to avoid interactions with await
|
||||
|
||||
var quwi = new QUWITaskScheduler();
|
||||
RunWithSchedulerAsCurrent(quwi, delegate
|
||||
{
|
||||
Assert.True(TaskScheduler.Current == quwi, "Expected to be on target scheduler");
|
||||
|
||||
// Create the not completed task and get its awaiter
|
||||
var mres = new ManualResetEventSlim();
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
|
||||
// Hook up the callback
|
||||
bool ranOnScheduler = false;
|
||||
Action callback = () =>
|
||||
{
|
||||
ranOnScheduler = (TaskScheduler.Current == quwi);
|
||||
mres.Set();
|
||||
};
|
||||
if (generic)
|
||||
{
|
||||
if (continueOnCapturedContext.HasValue) tcs.Task.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().OnCompleted(callback);
|
||||
else tcs.Task.GetAwaiter().OnCompleted(callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (continueOnCapturedContext.HasValue) ((Task)tcs.Task).ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().OnCompleted(callback);
|
||||
else ((Task)tcs.Task).GetAwaiter().OnCompleted(callback);
|
||||
}
|
||||
Assert.False(mres.IsSet, "Callback should not yet have run.");
|
||||
|
||||
// Complete the task in another scheduler and wait for the callback to run
|
||||
Task.Run(delegate { tcs.SetResult(null); });
|
||||
mres.Wait();
|
||||
|
||||
// Validate the callback ran on the right scheduler
|
||||
bool shouldHaveRunOnScheduler = !continueOnCapturedContext.HasValue || continueOnCapturedContext.Value;
|
||||
Assert.Equal(shouldHaveRunOnScheduler, ranOnScheduler);
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
SynchronizationContext.SetSynchronizationContext(origCtx);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GetResult_Completed_Success()
|
||||
{
|
||||
Task task = Task.CompletedTask;
|
||||
task.GetAwaiter().GetResult();
|
||||
task.ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
task.ConfigureAwait(true).GetAwaiter().GetResult();
|
||||
|
||||
const string expectedResult = "42";
|
||||
Task<string> taskOfString = Task.FromResult(expectedResult);
|
||||
Assert.Equal(expectedResult, taskOfString.GetAwaiter().GetResult());
|
||||
Assert.Equal(expectedResult, taskOfString.ConfigureAwait(false).GetAwaiter().GetResult());
|
||||
Assert.Equal(expectedResult, taskOfString.ConfigureAwait(true).GetAwaiter().GetResult());
|
||||
}
|
||||
|
||||
[OuterLoop]
|
||||
[Fact]
|
||||
public static void GetResult_NotCompleted_BlocksUntilCompletion()
|
||||
{
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
|
||||
// Kick off tasks that should all block
|
||||
var tasks = new[] {
|
||||
Task.Run(() => tcs.Task.GetAwaiter().GetResult()),
|
||||
Task.Run(() => ((Task)tcs.Task).GetAwaiter().GetResult()),
|
||||
Task.Run(() => tcs.Task.ConfigureAwait(false).GetAwaiter().GetResult()),
|
||||
Task.Run(() => ((Task)tcs.Task).ConfigureAwait(false).GetAwaiter().GetResult())
|
||||
};
|
||||
Assert.Equal(-1, Task.WaitAny(tasks, 100)); // "Tasks should not have completed"
|
||||
|
||||
// Now complete the tasks, after which all the tasks should complete successfully.
|
||||
tcs.SetResult(true);
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GetResult_CanceledTask_ThrowsCancellationException()
|
||||
{
|
||||
// Validate cancellation
|
||||
Task<string> canceled = Task.FromCanceled<string>(new CancellationToken(true));
|
||||
|
||||
// Task.GetAwaiter and Task<T>.GetAwaiter
|
||||
Assert.Throws<TaskCanceledException>(() => ((Task)canceled).GetAwaiter().GetResult());
|
||||
Assert.Throws<TaskCanceledException>(() => canceled.GetAwaiter().GetResult());
|
||||
|
||||
// w/ ConfigureAwait false and true
|
||||
Assert.Throws<TaskCanceledException>(() => ((Task)canceled).ConfigureAwait(false).GetAwaiter().GetResult());
|
||||
Assert.Throws<TaskCanceledException>(() => ((Task)canceled).ConfigureAwait(true).GetAwaiter().GetResult());
|
||||
Assert.Throws<TaskCanceledException>(() => canceled.ConfigureAwait(false).GetAwaiter().GetResult());
|
||||
Assert.Throws<TaskCanceledException>(() => canceled.ConfigureAwait(true).GetAwaiter().GetResult());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GetResult_FaultedTask_OneException_ThrowsOriginalException()
|
||||
{
|
||||
var exception = new ArgumentException("uh oh");
|
||||
Task<string> task = Task.FromException<string>(exception);
|
||||
|
||||
// Task.GetAwaiter and Task<T>.GetAwaiter
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => ((Task)task).GetAwaiter().GetResult()));
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => task.GetAwaiter().GetResult()));
|
||||
|
||||
// w/ ConfigureAwait false and true
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => ((Task)task).ConfigureAwait(false).GetAwaiter().GetResult()));
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => ((Task)task).ConfigureAwait(true).GetAwaiter().GetResult()));
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => task.ConfigureAwait(false).GetAwaiter().GetResult()));
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => task.ConfigureAwait(true).GetAwaiter().GetResult()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GetResult_FaultedTask_MultipleExceptions_ThrowsFirstException()
|
||||
{
|
||||
var exception = new ArgumentException("uh oh");
|
||||
var tcs = new TaskCompletionSource<string>();
|
||||
tcs.SetException(new Exception[] { exception, new InvalidOperationException("uh oh") });
|
||||
Task<string> task = tcs.Task;
|
||||
|
||||
// Task.GetAwaiter and Task<T>.GetAwaiter
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => ((Task)task).GetAwaiter().GetResult()));
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => task.GetAwaiter().GetResult()));
|
||||
|
||||
// w/ ConfigureAwait false and true
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => ((Task)task).ConfigureAwait(false).GetAwaiter().GetResult()));
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => ((Task)task).ConfigureAwait(true).GetAwaiter().GetResult()));
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => task.ConfigureAwait(false).GetAwaiter().GetResult()));
|
||||
Assert.Same(exception, Assert.Throws<ArgumentException>(() => task.ConfigureAwait(true).GetAwaiter().GetResult()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void AwaiterAndAwaitableEquality()
|
||||
{
|
||||
var completed = new TaskCompletionSource<string>();
|
||||
Task task = completed.Task;
|
||||
|
||||
// TaskAwaiter
|
||||
task.GetAwaiter().Equals(task.GetAwaiter());
|
||||
|
||||
// ConfiguredTaskAwaitable
|
||||
Assert.Equal(task.ConfigureAwait(false), task.ConfigureAwait(false));
|
||||
Assert.NotEqual(task.ConfigureAwait(false), task.ConfigureAwait(true));
|
||||
Assert.NotEqual(task.ConfigureAwait(true), task.ConfigureAwait(false));
|
||||
|
||||
// ConfiguredTaskAwaitable<T>
|
||||
Assert.Equal(task.ConfigureAwait(false), task.ConfigureAwait(false));
|
||||
Assert.NotEqual(task.ConfigureAwait(false), task.ConfigureAwait(true));
|
||||
Assert.NotEqual(task.ConfigureAwait(true), task.ConfigureAwait(false));
|
||||
|
||||
// ConfiguredTaskAwaitable.ConfiguredTaskAwaiter
|
||||
Assert.Equal(task.ConfigureAwait(false).GetAwaiter(), task.ConfigureAwait(false).GetAwaiter());
|
||||
Assert.NotEqual(task.ConfigureAwait(false).GetAwaiter(), task.ConfigureAwait(true).GetAwaiter());
|
||||
Assert.NotEqual(task.ConfigureAwait(true).GetAwaiter(), task.ConfigureAwait(false).GetAwaiter());
|
||||
|
||||
// ConfiguredTaskAwaitable<T>.ConfiguredTaskAwaiter
|
||||
Assert.Equal(task.ConfigureAwait(false).GetAwaiter(), task.ConfigureAwait(false).GetAwaiter());
|
||||
Assert.NotEqual(task.ConfigureAwait(false).GetAwaiter(), task.ConfigureAwait(true).GetAwaiter());
|
||||
Assert.NotEqual(task.ConfigureAwait(true).GetAwaiter(), task.ConfigureAwait(false).GetAwaiter());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void BaseSynchronizationContext_SameAsNoSynchronizationContext()
|
||||
{
|
||||
var quwi = new QUWITaskScheduler();
|
||||
SynchronizationContext origCtx = SynchronizationContext.Current;
|
||||
try
|
||||
{
|
||||
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
|
||||
RunWithSchedulerAsCurrent(quwi, delegate
|
||||
{
|
||||
ManualResetEventSlim mres = new ManualResetEventSlim();
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
var awaiter = ((Task)tcs.Task).GetAwaiter();
|
||||
|
||||
bool ranOnScheduler = false;
|
||||
bool ranWithoutSyncCtx = false;
|
||||
awaiter.OnCompleted(() =>
|
||||
{
|
||||
ranOnScheduler = (TaskScheduler.Current == quwi);
|
||||
ranWithoutSyncCtx = SynchronizationContext.Current == null;
|
||||
mres.Set();
|
||||
});
|
||||
Assert.False(mres.IsSet, "Callback should not yet have run.");
|
||||
|
||||
Task.Run(delegate { tcs.SetResult(null); });
|
||||
mres.Wait();
|
||||
|
||||
Assert.True(ranOnScheduler, "Should have run on scheduler");
|
||||
Assert.True(ranWithoutSyncCtx, "Should have run with a null sync ctx");
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
SynchronizationContext.SetSynchronizationContext(origCtx);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(CanceledTasksAndExpectedCancellationExceptions))]
|
||||
public static void OperationCanceledException_PropagatesThroughCanceledTask(int lineNumber, Task task, OperationCanceledException expected)
|
||||
{
|
||||
var caught = Assert.ThrowsAny<OperationCanceledException>(() => task.GetAwaiter().GetResult());
|
||||
Assert.Same(expected, caught);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> CanceledTasksAndExpectedCancellationExceptions()
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
var oce = new OperationCanceledException(cts.Token);
|
||||
|
||||
// Scheduled Task
|
||||
Task<int> generic = Task.Run<int>(new Func<int>(() =>
|
||||
{
|
||||
cts.Cancel();
|
||||
throw oce;
|
||||
}), cts.Token);
|
||||
yield return new object[] { LineNumber(), generic, oce };
|
||||
|
||||
Task nonGeneric = generic;
|
||||
|
||||
// WhenAll Task and Task<int>
|
||||
yield return new object[] { LineNumber(), Task.WhenAll(generic), oce };
|
||||
yield return new object[] { LineNumber(), Task.WhenAll(generic, Task.FromResult(42)), oce };
|
||||
yield return new object[] { LineNumber(), Task.WhenAll(Task.FromResult(42), generic), oce };
|
||||
yield return new object[] { LineNumber(), Task.WhenAll(generic, generic, generic), oce };
|
||||
yield return new object[] { LineNumber(), Task.WhenAll(nonGeneric), oce };
|
||||
yield return new object[] { LineNumber(), Task.WhenAll(nonGeneric, Task.FromResult(42)), oce };
|
||||
yield return new object[] { LineNumber(), Task.WhenAll(Task.FromResult(42), nonGeneric), oce };
|
||||
yield return new object[] { LineNumber(), Task.WhenAll(nonGeneric, nonGeneric, nonGeneric), oce };
|
||||
|
||||
// Task.Run Task and Task<int> with unwrapping
|
||||
yield return new object[] { LineNumber(), Task.Run(() => generic), oce };
|
||||
yield return new object[] { LineNumber(), Task.Run(() => nonGeneric), oce };
|
||||
|
||||
// A FromAsync Task and Task<int>
|
||||
yield return new object[] { LineNumber(), Task.Factory.FromAsync(generic, new Action<IAsyncResult>(ar => { throw oce; })), oce };
|
||||
yield return new object[] { LineNumber(), Task<int>.Factory.FromAsync(nonGeneric, new Func<IAsyncResult, int>(ar => { throw oce; })), oce };
|
||||
|
||||
// AsyncTaskMethodBuilder
|
||||
var atmb = new AsyncTaskMethodBuilder();
|
||||
atmb.SetException(oce);
|
||||
yield return new object[] { LineNumber(), atmb.Task, oce };
|
||||
}
|
||||
|
||||
private static int LineNumber([CallerLineNumber]int lineNumber = 0) => lineNumber;
|
||||
|
||||
private class ValidateCorrectContextSynchronizationContext : SynchronizationContext
|
||||
{
|
||||
[ThreadStatic]
|
||||
internal static bool IsPostedInContext;
|
||||
|
||||
internal int PostCount;
|
||||
internal int SendCount;
|
||||
|
||||
public override void Post(SendOrPostCallback d, object state)
|
||||
{
|
||||
Interlocked.Increment(ref PostCount);
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
IsPostedInContext = true;
|
||||
d(state);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsPostedInContext = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void Send(SendOrPostCallback d, object state)
|
||||
{
|
||||
Interlocked.Increment(ref SendCount);
|
||||
d(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>A scheduler that queues to the TP and tracks the number of times QueueTask and TryExecuteTaskInline are invoked.</summary>
|
||||
private class QUWITaskScheduler : TaskScheduler
|
||||
{
|
||||
private int _queueTaskCount;
|
||||
private int _tryExecuteTaskInlineCount;
|
||||
|
||||
public int QueueTaskCount { get { return _queueTaskCount; } }
|
||||
public int TryExecuteTaskInlineCount { get { return _tryExecuteTaskInlineCount; } }
|
||||
|
||||
protected override IEnumerable<Task> GetScheduledTasks() { return null; }
|
||||
|
||||
protected override void QueueTask(Task task)
|
||||
{
|
||||
Interlocked.Increment(ref _queueTaskCount);
|
||||
Task.Run(() => TryExecuteTask(task));
|
||||
}
|
||||
|
||||
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
|
||||
{
|
||||
Interlocked.Increment(ref _tryExecuteTaskInlineCount);
|
||||
return TryExecuteTask(task);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Runs the action with TaskScheduler.Current equal to the specified scheduler.</summary>
|
||||
private static void RunWithSchedulerAsCurrent(TaskScheduler scheduler, Action action)
|
||||
{
|
||||
var t = new Task(action);
|
||||
t.RunSynchronously(scheduler);
|
||||
t.GetAwaiter().GetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Xunit;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.Threading.Tasks.Tests
|
||||
{
|
||||
public class YieldAwaitableTests
|
||||
{
|
||||
// awaiting Task.Yield
|
||||
[Fact]
|
||||
public static void RunAsyncYieldAwaiterTests()
|
||||
{
|
||||
// Test direct usage works even though it's not encouraged
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
SynchronizationContext.SetSynchronizationContext(new ValidateCorrectContextSynchronizationContext());
|
||||
var ya = i == 0 ? new YieldAwaitable.YieldAwaiter() : new YieldAwaitable().GetAwaiter();
|
||||
var mres = new ManualResetEventSlim();
|
||||
Assert.False(ya.IsCompleted, "RunAsyncYieldAwaiterTests > FAILURE. YieldAwaiter.IsCompleted should always be false.");
|
||||
ya.OnCompleted(() =>
|
||||
{
|
||||
Assert.True(ValidateCorrectContextSynchronizationContext.IsPostedInContext, "RunAsyncYieldAwaiterTests > FAILURE. Expected to post in target context.");
|
||||
mres.Set();
|
||||
});
|
||||
mres.Wait();
|
||||
ya.GetResult();
|
||||
SynchronizationContext.SetSynchronizationContext(null);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Yield when there's a current sync context
|
||||
SynchronizationContext.SetSynchronizationContext(new ValidateCorrectContextSynchronizationContext());
|
||||
var ya = Task.Yield().GetAwaiter();
|
||||
try { ya.GetResult(); }
|
||||
catch
|
||||
{
|
||||
Assert.True(false, string.Format("RunAsyncYieldAwaiterTests > FAILURE. YieldAwaiter.GetResult threw inappropriately"));
|
||||
}
|
||||
var mres = new ManualResetEventSlim();
|
||||
Assert.False(ya.IsCompleted, "RunAsyncYieldAwaiterTests > FAILURE. YieldAwaiter.IsCompleted should always be false.");
|
||||
ya.OnCompleted(() =>
|
||||
{
|
||||
Assert.True(ValidateCorrectContextSynchronizationContext.IsPostedInContext, " > FAILURE. Expected to post in target context.");
|
||||
mres.Set();
|
||||
});
|
||||
mres.Wait();
|
||||
ya.GetResult();
|
||||
SynchronizationContext.SetSynchronizationContext(null);
|
||||
}
|
||||
|
||||
{
|
||||
// Yield when there's a current TaskScheduler
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var ya = Task.Yield().GetAwaiter();
|
||||
try { ya.GetResult(); }
|
||||
catch
|
||||
{
|
||||
Assert.True(false, string.Format(" > FAILURE. YieldAwaiter.GetResult threw inappropriately"));
|
||||
}
|
||||
var mres = new ManualResetEventSlim();
|
||||
Assert.False(ya.IsCompleted, " > FAILURE. YieldAwaiter.IsCompleted should always be false.");
|
||||
ya.OnCompleted(() =>
|
||||
{
|
||||
Assert.True(TaskScheduler.Current is QUWITaskScheduler, " > FAILURE. Expected to queue into target scheduler.");
|
||||
mres.Set();
|
||||
});
|
||||
mres.Wait();
|
||||
ya.GetResult();
|
||||
}
|
||||
catch { Assert.True(false, string.Format(" > FAILURE. Unexpected exception from Yield")); }
|
||||
}, CancellationToken.None, TaskCreationOptions.None, new QUWITaskScheduler()).Wait();
|
||||
}
|
||||
|
||||
{
|
||||
// Yield when there's a current TaskScheduler and SynchronizationContext.Current is the base SynchronizationContext
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
|
||||
try
|
||||
{
|
||||
var ya = Task.Yield().GetAwaiter();
|
||||
try { ya.GetResult(); }
|
||||
catch
|
||||
{
|
||||
Assert.True(false, string.Format(" > FAILURE. YieldAwaiter.GetResult threw inappropriately"));
|
||||
}
|
||||
var mres = new ManualResetEventSlim();
|
||||
Assert.False(ya.IsCompleted, " > FAILURE. YieldAwaiter.IsCompleted should always be false.");
|
||||
ya.OnCompleted(() =>
|
||||
{
|
||||
Assert.True(TaskScheduler.Current is QUWITaskScheduler, " > FAILURE. Expected to queue into target scheduler.");
|
||||
mres.Set();
|
||||
});
|
||||
mres.Wait();
|
||||
ya.GetResult();
|
||||
}
|
||||
catch { Assert.True(false, string.Format(" > FAILURE. Unexpected exception from Yield")); }
|
||||
SynchronizationContext.SetSynchronizationContext(null);
|
||||
}, CancellationToken.None, TaskCreationOptions.None, new QUWITaskScheduler()).Wait();
|
||||
}
|
||||
|
||||
{
|
||||
// OnCompleted grabs the current context, not Task.Yield nor GetAwaiter
|
||||
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
|
||||
var ya = Task.Yield().GetAwaiter();
|
||||
SynchronizationContext.SetSynchronizationContext(new ValidateCorrectContextSynchronizationContext());
|
||||
try { ya.GetResult(); }
|
||||
catch
|
||||
{
|
||||
Assert.True(false, string.Format(" > FAILURE. YieldAwaiter.GetResult threw inappropriately"));
|
||||
}
|
||||
var mres = new ManualResetEventSlim();
|
||||
Assert.False(ya.IsCompleted, " > FAILURE. YieldAwaiter.IsCompleted should always be false.");
|
||||
ya.OnCompleted(() =>
|
||||
{
|
||||
Assert.True(ValidateCorrectContextSynchronizationContext.IsPostedInContext, " > FAILURE. Expected to post in target context.");
|
||||
mres.Set();
|
||||
});
|
||||
mres.Wait();
|
||||
ya.GetResult();
|
||||
SynchronizationContext.SetSynchronizationContext(null);
|
||||
}
|
||||
}
|
||||
|
||||
// awaiting Task.Yield
|
||||
[Fact]
|
||||
public static void RunAsyncYieldAwaiterTests_Negative()
|
||||
{
|
||||
// Yield when there's a current sync context
|
||||
SynchronizationContext.SetSynchronizationContext(new ValidateCorrectContextSynchronizationContext());
|
||||
var ya = Task.Yield().GetAwaiter();
|
||||
Assert.Throws<ArgumentNullException>(() => { ya.OnCompleted(null); });
|
||||
}
|
||||
|
||||
#region Helper Methods / Classes
|
||||
|
||||
private class ValidateCorrectContextSynchronizationContext : SynchronizationContext
|
||||
{
|
||||
[ThreadStatic]
|
||||
internal static bool IsPostedInContext;
|
||||
|
||||
internal int PostCount;
|
||||
internal int SendCount;
|
||||
|
||||
public override void Post(SendOrPostCallback d, object state)
|
||||
{
|
||||
Interlocked.Increment(ref PostCount);
|
||||
Task.Run(() =>
|
||||
{
|
||||
IsPostedInContext = true;
|
||||
d(state);
|
||||
IsPostedInContext = false;
|
||||
});
|
||||
}
|
||||
|
||||
public override void Send(SendOrPostCallback d, object state)
|
||||
{
|
||||
Interlocked.Increment(ref SendCount);
|
||||
d(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>A scheduler that queues to the TP and tracks the number of times QueueTask and TryExecuteTaskInline are invoked.</summary>
|
||||
private class QUWITaskScheduler : TaskScheduler
|
||||
{
|
||||
private int _queueTaskCount;
|
||||
private int _tryExecuteTaskInlineCount;
|
||||
|
||||
public int QueueTaskCount { get { return _queueTaskCount; } }
|
||||
public int TryExecuteTaskInlineCount { get { return _tryExecuteTaskInlineCount; } }
|
||||
|
||||
protected override IEnumerable<Task> GetScheduledTasks() { return null; }
|
||||
|
||||
protected override void QueueTask(Task task)
|
||||
{
|
||||
Interlocked.Increment(ref _queueTaskCount);
|
||||
Task.Run(() => TryExecuteTask(task));
|
||||
}
|
||||
|
||||
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
|
||||
{
|
||||
Interlocked.Increment(ref _tryExecuteTaskInlineCount);
|
||||
return TryExecuteTask(task);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user