소스 검색

Merge pull request #1291 from dotnet/dotnet5

.NET 5 support for Rx.NET
Claire Novotny 5 년 전
부모
커밋
8a2df0b785
35개의 변경된 파일207개의 추가작업 그리고 167개의 파일을 삭제
  1. 5 5
      Rx.NET/Integration/LinuxTests/LinuxTests.csproj
  2. 8 5
      Rx.NET/Integration/WindowsDesktopTests/WindowsDesktopTests.csproj
  3. 1 4
      Rx.NET/Integration/global.json
  4. 0 1
      Rx.NET/Source/Directory.build.props
  5. 25 26
      Rx.NET/Source/Directory.build.targets
  6. 1 1
      Rx.NET/Source/facades/System.Reactive.Core/System.Reactive.Core.csproj
  7. 1 1
      Rx.NET/Source/facades/System.Reactive.Interfaces/System.Reactive.Interfaces.csproj
  8. 1 1
      Rx.NET/Source/facades/System.Reactive.Linq/System.Reactive.Linq.csproj
  9. 1 1
      Rx.NET/Source/facades/System.Reactive.PlatformServices/System.Reactive.PlatformServices.csproj
  10. 1 1
      Rx.NET/Source/facades/System.Reactive.Providers/System.Reactive.Providers.csproj
  11. 1 1
      Rx.NET/Source/facades/System.Reactive.Windows.Threading/System.Reactive.Windows.Threading.csproj
  12. 4 2
      Rx.NET/Source/facades/System.Reactive.Windows.Threading/TypeForwarders.Threading.cs
  13. 1 1
      Rx.NET/Source/facades/System.Reactive.WindowsRuntime/System.Reactive.WindowsRuntime.csproj
  14. 3 0
      Rx.NET/Source/global.json
  15. 1 1
      Rx.NET/Source/src/Microsoft.Reactive.Testing/Microsoft.Reactive.Testing.csproj
  16. 1 1
      Rx.NET/Source/src/System.Reactive.Observable.Aliases/System.Reactive.Observable.Aliases.csproj
  17. 1 1
      Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.Windows.cs
  18. 1 1
      Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.cs
  19. 1 1
      Rx.NET/Source/src/System.Reactive/Internal/CurrentPlatformEnlightenmentProvider.cs
  20. 1 1
      Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs
  21. 4 4
      Rx.NET/Source/src/System.Reactive/Linq/Observable.Binding.cs
  22. 2 2
      Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Concurrency/ControlScheduler.cs
  23. 18 18
      Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Concurrency/DispatcherScheduler.cs
  24. 1 1
      Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Internal/Constants.cs
  25. 1 1
      Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Linq/DispatcherObservable.cs
  26. 36 9
      Rx.NET/Source/src/System.Reactive/Platforms/UWP/Concurrency/CoreDispatcherScheduler.cs
  27. 20 14
      Rx.NET/Source/src/System.Reactive/Platforms/UWP/Linq/CoreDispatcherObservable.cs
  28. 16 18
      Rx.NET/Source/src/System.Reactive/System.Reactive.csproj
  29. 1 1
      Rx.NET/Source/src/System.Reactive/build/System.Reactive.targets
  30. 2 2
      Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Tests.System.Reactive.ApiApprovals.csproj
  31. 1 1
      Rx.NET/Source/tests/Tests.System.Reactive/DispatcherHelpers.cs
  32. 2 2
      Rx.NET/Source/tests/Tests.System.Reactive/Tests.System.Reactive.csproj
  33. 7 7
      Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/DispatcherSchedulerTest.cs
  34. 2 2
      Rx.NET/Source/version.json
  35. 35 29
      azure-pipelines.rx.yml

+ 5 - 5
Rx.NET/Integration/LinuxTests/LinuxTests.csproj

@@ -1,6 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0;netcoreapp2.1</TargetFrameworks>
+    <TargetFrameworks>netcoreapp3.1;netcoreapp2.1;net5.0</TargetFrameworks>
     <NoWarn>$(NoWarn);CS0618</NoWarn>
     <LangVersion>latest</LangVersion>
     <AssemblyName>Tests.System.Reactive</AssemblyName>
@@ -10,10 +10,10 @@
   </PropertyGroup>
   
   <PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp2.1'">
-    <DefineConstants>$(DefineConstants);HAS_TRACE;HAS_WINRT;PREFER_ASYNC;HAS_TPL46;NO_REMOTING</DefineConstants>
+    <DefineConstants>$(DefineConstants);</DefineConstants>
   </PropertyGroup>
-  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <DefineConstants>$(DefineConstants);HAS_TRACE;HAS_WINRT;PREFER_ASYNC;HAS_TPL46;NO_REMOTING;LINUX</DefineConstants>
+  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net5.0' ">
+    <DefineConstants>$(DefineConstants);LINUX</DefineConstants>
   </PropertyGroup>
 
   <ItemGroup>
@@ -24,7 +24,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.0-preview-20181205-02" />    
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />    
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
     <PackageReference Include="System.Reactive" Version="4.2.0-preview.63" />

+ 8 - 5
Rx.NET/Integration/WindowsDesktopTests/WindowsDesktopTests.csproj

@@ -1,6 +1,6 @@
-<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFrameworks>netcoreapp3.1;net5.0;net5.0-windows10.0.19041</TargetFrameworks>
     <NoWarn>$(NoWarn);CS0618</NoWarn>
     <LangVersion>latest</LangVersion>
     <AssemblyName>Tests.System.Reactive</AssemblyName>
@@ -12,8 +12,11 @@
   </PropertyGroup>
   
 
-  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <DefineConstants>$(DefineConstants);HAS_TRACE;HAS_WINRT;PREFER_ASYNC;HAS_TPL46;NO_REMOTING;HAS_WINFORMS;HAS_DISPATCHER;DESKTOPCLR</DefineConstants>
+  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
+    <DefineConstants>$(DefineConstants);HAS_WINRT;HAS_WINFORMS;HAS_WPF;HAS_DISPATCHER;DESKTOPCLR</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition="$(TargetFramework.StartsWith('net5.0-windows'))">
+    <DefineConstants>$(DefineConstants);HAS_TRACE;HAS_WINRT;PREFER_ASYNC;HAS_TPL46;NO_REMOTING;HAS_WINFORMS;HAS_WPF;HAS_DISPATCHER;DESKTOPCLR;WINDOWS;CSWINRT</DefineConstants>
   </PropertyGroup>
 
   <ItemGroup>
@@ -24,7 +27,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.0-preview-20190203-03" />    
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />    
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
     <PackageReference Include="System.Reactive" Version="4.2.0-preview.63" />

+ 1 - 4
Rx.NET/Integration/global.json

@@ -1,8 +1,5 @@
 {
-  "sdk": {
-    "version": "3.0.100-preview"
-  },
   "msbuild-sdks": {
-    "MSBuild.Sdk.Extras": "2.0.31"
+    "MSBuild.Sdk.Extras": "2.1.2"
   }
 }

+ 0 - 1
Rx.NET/Source/Directory.build.props

@@ -24,7 +24,6 @@
 
   <PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
     <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
-    <Deterministic>true</Deterministic>
   </PropertyGroup>
 
   <ItemGroup>

+ 25 - 26
Rx.NET/Source/Directory.build.targets

@@ -1,46 +1,34 @@
 <Project>
 
-  <!-- Workaround. Remove once we're on 3.1.300+
-  https://github.com/dotnet/sourcelink/issues/572 -->
-  <PropertyGroup>
-    <TargetFrameworkMonikerAssemblyAttributesPath>$([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))</TargetFrameworkMonikerAssemblyAttributesPath>
-  </PropertyGroup>
-  <ItemGroup>
-    <EmbeddedFiles Include="$(GeneratedAssemblyInfoFile)"/>
-  </ItemGroup>
-
-
   <!-- This props all need to be set in targets as they depend on the values set earlier -->
   
   <PropertyGroup>  
     <Product>$(AssemblyName) ($(TargetFramework))</Product>
   </PropertyGroup>
-
-  <PropertyGroup>
-    <DefineConstants>$(DefineConstants);HAS_WINRT</DefineConstants>
-  </PropertyGroup>
     
   <PropertyGroup Condition="'$(TargetFramework)' == 'net46'">
-    <DefineConstants>$(DefineConstants);HAS_WINFORMS;HAS_DISPATCHER;HAS_REMOTING;DESKTOPCLR</DefineConstants>
+    <DefineConstants>$(DefineConstants);HAS_WINFORMS;HAS_WPF;HAS_WINRT;HAS_DISPATCHER;HAS_REMOTING;DESKTOPCLR</DefineConstants>
   </PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0'">
-    <TargetPlatformVersion>10.0.17763.0</TargetPlatformVersion>
+    <TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
     <TargetPlatformMinVersion>10.0.15063.0</TargetPlatformMinVersion>
-    <DefineConstants>$(DefineConstants);NO_CODE_COVERAGE_ATTRIBUTE;NO_SERIALIZABLE;CRIPPLED_REFLECTION;NO_THREAD;NO_TRACE;WINDOWS</DefineConstants>
+    <DefineConstants>$(DefineConstants);HAS_WINRT;NO_CODE_COVERAGE_ATTRIBUTE;NO_SERIALIZABLE;CRIPPLED_REFLECTION;NO_THREAD;NO_TRACE;WINDOWS</DefineConstants>
   </PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0.16299'">
-    <DefineConstants>$(DefineConstants);WINDOWS</DefineConstants>
-    <TargetPlatformVersion>10.0.17763.0</TargetPlatformVersion>
+    <DefineConstants>$(DefineConstants);HAS_WINRT;WINDOWS;HAS_OS_XAML;LEGACY_WINRT</DefineConstants>
+    <TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
   </PropertyGroup>
   <PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp2.1'">
-    <DefineConstants>$(DefineConstants)</DefineConstants>
+    <DefineConstants>$(DefineConstants);HAS_WINRT</DefineConstants>
   </PropertyGroup>
-  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <DefineConstants>$(DefineConstants);HAS_WINFORMS;HAS_DISPATCHER;DESKTOPCLR</DefineConstants>
+  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
+    <DefineConstants>$(DefineConstants);HAS_WINRT;HAS_WINFORMS;HAS_WPF;HAS_DISPATCHER;DESKTOPCLR</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition="$(TargetFramework.StartsWith('net5.0-windows'))">
+    <DefineConstants>$(DefineConstants);HAS_WINRT;HAS_WINFORMS;HAS_WPF;HAS_DISPATCHER;DESKTOPCLR;WINDOWS;CSWINRT</DefineConstants>
   </PropertyGroup>
 
-
-  <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.0'">
+  <ItemGroup Condition="'$(TargetFramework)' == 'net46' or '$(TargetFramework)' == 'uap10.0' or '$(TargetFramework)' == 'uap10.0.16299' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netcoreapp2.1'">
     <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
   </ItemGroup>
 
@@ -52,5 +40,16 @@
       </AssemblyAttribute>
     </ItemGroup>
   </Target>
-  
-</Project>
+
+
+  <!-- Remove once coverlet supports this built-in -->
+  <Target Name="CoverletGetPathMap"
+          DependsOnTargets="InitializeSourceRootMappedPaths"
+          Returns="@(_LocalTopLevelSourceRoot)"
+          Condition="'$(DeterministicSourcePaths)' == 'true'">
+    <ItemGroup>
+      <_LocalTopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/>
+    </ItemGroup>
+  </Target>
+
+</Project>

+ 1 - 1
Rx.NET/Source/facades/System.Reactive.Core/System.Reactive.Core.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="MSBuild.Sdk.Extras">
 
   <PropertyGroup>
-    <TargetFrameworks>net46;netstandard2.0;uap10.0</TargetFrameworks>
+    <TargetFrameworks>net46;netstandard2.0;uap10.0.16299</TargetFrameworks>
   </PropertyGroup>
 
   <ItemGroup>

+ 1 - 1
Rx.NET/Source/facades/System.Reactive.Interfaces/System.Reactive.Interfaces.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="MSBuild.Sdk.Extras">
 
   <PropertyGroup>
-    <TargetFrameworks>net46;netstandard2.0;uap10.0</TargetFrameworks>
+    <TargetFrameworks>net46;netstandard2.0;uap10.0.16299</TargetFrameworks>
   </PropertyGroup>
 
   <ItemGroup>

+ 1 - 1
Rx.NET/Source/facades/System.Reactive.Linq/System.Reactive.Linq.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="MSBuild.Sdk.Extras">
 
   <PropertyGroup>
-    <TargetFrameworks>net46;netstandard2.0;uap10.0</TargetFrameworks>
+    <TargetFrameworks>net46;netstandard2.0;uap10.0.16299</TargetFrameworks>
   </PropertyGroup>
 
   <ItemGroup>

+ 1 - 1
Rx.NET/Source/facades/System.Reactive.PlatformServices/System.Reactive.PlatformServices.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="MSBuild.Sdk.Extras">
 
   <PropertyGroup>
-    <TargetFrameworks>net46;netstandard2.0;uap10.0</TargetFrameworks>
+    <TargetFrameworks>net46;netstandard2.0;uap10.0.16299</TargetFrameworks>
   </PropertyGroup>
 
   <ItemGroup>

+ 1 - 1
Rx.NET/Source/facades/System.Reactive.Providers/System.Reactive.Providers.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="MSBuild.Sdk.Extras">
 
   <PropertyGroup>
-    <TargetFrameworks>net46;netstandard2.0;uap10.0</TargetFrameworks>
+    <TargetFrameworks>net46;netstandard2.0;uap10.0.16299</TargetFrameworks>
   </PropertyGroup>
 
   <ItemGroup>

+ 1 - 1
Rx.NET/Source/facades/System.Reactive.Windows.Threading/System.Reactive.Windows.Threading.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="MSBuild.Sdk.Extras">
 
   <PropertyGroup>
-    <TargetFrameworks>net46;uap10.0</TargetFrameworks>
+    <TargetFrameworks>net46;uap10.0.16299</TargetFrameworks>
   </PropertyGroup>
 
   <ItemGroup>

+ 4 - 2
Rx.NET/Source/facades/System.Reactive.Windows.Threading/TypeForwarders.Threading.cs

@@ -1,10 +1,12 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
 
 #if WINDOWS
 [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Reactive.Concurrency.CoreDispatcherScheduler))]
+[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Reactive.Linq.CoreDispatcherObservable))]
 #else
 [assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Reactive.Concurrency.DispatcherScheduler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Reactive.Linq.DispatcherObservable))]
 #endif
-[assembly:System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Reactive.Linq.DispatcherObservable))]
+

+ 1 - 1
Rx.NET/Source/facades/System.Reactive.WindowsRuntime/System.Reactive.WindowsRuntime.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="MSBuild.Sdk.Extras">
 
   <PropertyGroup>
-    <TargetFramework>uap10.0</TargetFramework>
+    <TargetFramework>uap10.0.16299</TargetFramework>
   </PropertyGroup>
 
   <ItemGroup>

+ 3 - 0
Rx.NET/Source/global.json

@@ -1,4 +1,7 @@
 {
+"sdk": {
+    "version": "5.0.100-preview"
+  },
   "msbuild-sdks": {
     "MSBuild.Sdk.Extras": "2.1.2"
   }

+ 1 - 1
Rx.NET/Source/src/Microsoft.Reactive.Testing/Microsoft.Reactive.Testing.csproj

@@ -1,6 +1,6 @@
 <Project Sdk="MSBuild.Sdk.Extras">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0;net46;uap10.0;netstandard2.0</TargetFrameworks>
+    <TargetFrameworks>netcoreapp3.1;net46;uap10.0.16299;netstandard2.0;net5.0</TargetFrameworks>
     <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
     <Description>Reactive Extensions Testing Library containing interfaces and classes providing functionality to test applications and libraries built using Reactive Extensions.</Description>    
     <AssemblyTitle>Microsoft.Reactive.Testing - Testing Helper Library</AssemblyTitle>    

+ 1 - 1
Rx.NET/Source/src/System.Reactive.Observable.Aliases/System.Reactive.Observable.Aliases.csproj

@@ -1,6 +1,6 @@
 <Project Sdk="MSBuild.Sdk.Extras">
   <PropertyGroup>
-    <TargetFrameworks>netstandard2.0;net46;uap10.0</TargetFrameworks>    
+    <TargetFrameworks>netstandard2.0;net46;uap10.0.16299;net5.0</TargetFrameworks>    
     <Title>Reactive Extensions - Aliases</Title>    
     <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>    
     <PackageTags>Rx;Reactive;Extensions;Observable;LINQ;Events</PackageTags>

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.Windows.cs

@@ -2,7 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT License.
 // See the LICENSE file in the project root for more information. 
 
-#if WINDOWS
+#if LEGACY_WINRT
 using System.ComponentModel;
 using Windows.System.Threading;
 

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Concurrency/ThreadPoolScheduler.cs

@@ -2,7 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT License.
 // See the LICENSE file in the project root for more information. 
 
-#if !WINDOWS && !NO_THREAD
+#if !LEGACY_WINRT && !NO_THREAD
 using System.Reactive.Disposables;
 using System.Threading;
 

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Internal/CurrentPlatformEnlightenmentProvider.cs

@@ -34,7 +34,7 @@ namespace System.Reactive.PlatformServices
                 return (T)(object)new ExceptionServicesImpl();
             }
 
-#if !NO_THREAD || WINDOWS
+#if !NO_THREAD || LEGACY_WINRT
             if (t == typeof(IConcurrencyAbstractionLayer))
             {
                 return (T)(object)new ConcurrencyAbstractionLayerImpl();

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs

@@ -71,7 +71,7 @@ namespace System.Reactive
 
             isWinRT = false;
 
-#if HAS_WINRT
+#if HAS_WINRT && !CSWINRT
             if (addMethod.ReturnType == typeof(EventRegistrationToken))
             {
                 isWinRT = true;

+ 4 - 4
Rx.NET/Source/src/System.Reactive/Linq/Observable.Binding.cs

@@ -256,7 +256,7 @@ namespace System.Reactive.Linq
 
             if (disconnectDelay < TimeSpan.Zero)
             {
-                throw new ArgumentException("disconnectDelay");
+                throw new ArgumentException("Delay cannot be less than zero", "disconnectDelay");
             }
 
             return s_impl.RefCount(source, disconnectDelay);
@@ -285,7 +285,7 @@ namespace System.Reactive.Linq
 
             if (disconnectDelay < TimeSpan.Zero)
             {
-                throw new ArgumentException("disconnectDelay");
+                throw new ArgumentException("Delay cannot be less than zero", "disconnectDelay");
             }
 
             return s_impl.RefCount(source, disconnectDelay, scheduler);
@@ -333,7 +333,7 @@ namespace System.Reactive.Linq
 
             if (disconnectDelay < TimeSpan.Zero)
             {
-                throw new ArgumentException("disconnectDelay");
+                throw new ArgumentException("Delay cannot be less than zero", "disconnectDelay");
             }
             if (minObservers <= 0)
             {
@@ -368,7 +368,7 @@ namespace System.Reactive.Linq
 
             if (disconnectDelay < TimeSpan.Zero)
             {
-                throw new ArgumentException("disconnectDelay");
+                throw new ArgumentException("Delay cannot be less than zero", "disconnectDelay");
             }
             if (minObservers <= 0)
             {

+ 2 - 2
Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Concurrency/ControlScheduler.cs

@@ -95,7 +95,7 @@ namespace System.Reactive.Concurrency
             {
                 var d = new MultipleAssignmentDisposable();
 
-                var timer = new Windows.Forms.Timer();
+                var timer = new System.Windows.Forms.Timer();
 
                 timer.Tick += (s, e) =>
                 {
@@ -174,7 +174,7 @@ namespace System.Reactive.Concurrency
 
             var createTimer = new Func<IScheduler, TState, IDisposable>((scheduler1, state1) =>
             {
-                var timer = new Windows.Forms.Timer();
+                var timer = new System.Windows.Forms.Timer();
 
                 timer.Tick += (s, e) =>
                 {

+ 18 - 18
Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Concurrency/DispatcherScheduler.cs

@@ -2,14 +2,14 @@
 // The .NET Foundation licenses this file to you under the MIT License.
 // See the LICENSE file in the project root for more information. 
 
-#if !WINDOWS
+#if HAS_WPF
 using System.Reactive.Disposables;
 using System.Threading;
 
 namespace System.Reactive.Concurrency
 {
     /// <summary>
-    /// Represents an object that schedules units of work on a <see cref="Windows.Threading.Dispatcher"/>.
+    /// Represents an object that schedules units of work on a <see cref="System.Windows.Threading.Dispatcher"/>.
     /// </summary>
     /// <remarks>
     /// This scheduler type is typically used indirectly through the <see cref="Linq.DispatcherObservable.ObserveOnDispatcher{TSource}(IObservable{TSource})"/> and <see cref="Linq.DispatcherObservable.SubscribeOnDispatcher{TSource}(IObservable{TSource})"/> methods that use the Dispatcher on the calling thread.
@@ -17,19 +17,19 @@ namespace System.Reactive.Concurrency
     public class DispatcherScheduler : LocalScheduler, ISchedulerPeriodic
     {
         /// <summary>
-        /// Gets the scheduler that schedules work on the current <see cref="Windows.Threading.Dispatcher"/>.
+        /// Gets the scheduler that schedules work on the current <see cref="System.Windows.Threading.Dispatcher"/>.
         /// </summary>
         [Obsolete(Constants_WindowsThreading.OBSOLETE_INSTANCE_PROPERTY)]
-        public static DispatcherScheduler Instance => new DispatcherScheduler(Windows.Threading.Dispatcher.CurrentDispatcher);
+        public static DispatcherScheduler Instance => new DispatcherScheduler(System.Windows.Threading.Dispatcher.CurrentDispatcher);
 
         /// <summary>
-        /// Gets the scheduler that schedules work on the <see cref="Windows.Threading.Dispatcher"/> for the current thread.
+        /// Gets the scheduler that schedules work on the <see cref="System.Windows.Threading.Dispatcher"/> for the current thread.
         /// </summary>
         public static DispatcherScheduler Current
         {
             get
             {
-                var dispatcher = Windows.Threading.Dispatcher.FromThread(Thread.CurrentThread);
+                var dispatcher = System.Windows.Threading.Dispatcher.FromThread(Thread.CurrentThread);
                 if (dispatcher == null)
                 {
                     throw new InvalidOperationException(Strings_WindowsThreading.NO_DISPATCHER_CURRENT_THREAD);
@@ -40,38 +40,38 @@ namespace System.Reactive.Concurrency
         }
 
         /// <summary>
-        /// Constructs a <see cref="DispatcherScheduler"/> that schedules units of work on the given <see cref="Windows.Threading.Dispatcher"/>.
+        /// Constructs a <see cref="DispatcherScheduler"/> that schedules units of work on the given <see cref="System.Windows.Threading.Dispatcher"/>.
         /// </summary>
         /// <param name="dispatcher"><see cref="DispatcherScheduler"/> to schedule work on.</param>
         /// <exception cref="ArgumentNullException"><paramref name="dispatcher"/> is <c>null</c>.</exception>
-        public DispatcherScheduler(Windows.Threading.Dispatcher dispatcher)
+        public DispatcherScheduler(System.Windows.Threading.Dispatcher dispatcher)
         {
             Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
-            Priority = Windows.Threading.DispatcherPriority.Normal;
+            Priority = System.Windows.Threading.DispatcherPriority.Normal;
 
         }
 
         /// <summary>
-        /// Constructs a <see cref="DispatcherScheduler"/> that schedules units of work on the given <see cref="Windows.Threading.Dispatcher"/> at the given priority.
+        /// Constructs a <see cref="DispatcherScheduler"/> that schedules units of work on the given <see cref="System.Windows.Threading.Dispatcher"/> at the given priority.
         /// </summary>
         /// <param name="dispatcher"><see cref="DispatcherScheduler"/> to schedule work on.</param>
         /// <param name="priority">Priority at which units of work are scheduled.</param>
         /// <exception cref="ArgumentNullException"><paramref name="dispatcher"/> is <c>null</c>.</exception>
-        public DispatcherScheduler(Windows.Threading.Dispatcher dispatcher, Windows.Threading.DispatcherPriority priority)
+        public DispatcherScheduler(System.Windows.Threading.Dispatcher dispatcher, System.Windows.Threading.DispatcherPriority priority)
         {
             Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
             Priority = priority;
         }
 
         /// <summary>
-        /// Gets the <see cref="Windows.Threading.Dispatcher"/> associated with the <see cref="DispatcherScheduler"/>.
+        /// Gets the <see cref="System.Windows.Threading.Dispatcher"/> associated with the <see cref="DispatcherScheduler"/>.
         /// </summary>
-        public Windows.Threading.Dispatcher Dispatcher { get; }
+        public System.Windows.Threading.Dispatcher Dispatcher { get; }
 
         /// <summary>
         /// Gets the priority at which work items will be dispatched.
         /// </summary>
-        public Windows.Threading.DispatcherPriority Priority { get; }
+        public System.Windows.Threading.DispatcherPriority Priority { get; }
 
         /// <summary>
         /// Schedules an action to be executed on the dispatcher.
@@ -105,7 +105,7 @@ namespace System.Reactive.Concurrency
         }
 
         /// <summary>
-        /// Schedules an action to be executed after <paramref name="dueTime"/> on the dispatcher, using a <see cref="Windows.Threading.DispatcherTimer"/> object.
+        /// Schedules an action to be executed after <paramref name="dueTime"/> on the dispatcher, using a <see cref="System.Windows.Threading.DispatcherTimer"/> object.
         /// </summary>
         /// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
         /// <param name="state">State passed to the action to be executed.</param>
@@ -133,7 +133,7 @@ namespace System.Reactive.Concurrency
         {
             var d = new MultipleAssignmentDisposable();
 
-            var timer = new Windows.Threading.DispatcherTimer(Priority, Dispatcher);
+            var timer = new System.Windows.Threading.DispatcherTimer(Priority, Dispatcher);
 
             timer.Tick += (s, e) =>
             {
@@ -169,7 +169,7 @@ namespace System.Reactive.Concurrency
         }
 
         /// <summary>
-        /// Schedules a periodic piece of work on the dispatcher, using a <see cref="Windows.Threading.DispatcherTimer"/> object.
+        /// Schedules a periodic piece of work on the dispatcher, using a <see cref="System.Windows.Threading.DispatcherTimer"/> object.
         /// </summary>
         /// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam>
         /// <param name="state">Initial state passed to the action upon the first iteration.</param>
@@ -190,7 +190,7 @@ namespace System.Reactive.Concurrency
                 throw new ArgumentNullException(nameof(action));
             }
 
-            var timer = new Windows.Threading.DispatcherTimer(Priority, Dispatcher);
+            var timer = new System.Windows.Threading.DispatcherTimer(Priority, Dispatcher);
 
             var state1 = state;
 

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Internal/Constants.cs

@@ -8,7 +8,7 @@ namespace System.Reactive
 
     internal static class Constants_WindowsThreading
     {
-#if !WINDOWS
+#if HAS_WPF
         public const string OBSOLETE_INSTANCE_PROPERTY = "Use the Current property to retrieve the DispatcherScheduler instance for the current thread's Dispatcher object.";
 #endif
     }

+ 1 - 1
Rx.NET/Source/src/System.Reactive/Platforms/Desktop/Linq/DispatcherObservable.cs

@@ -2,7 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT License.
 // See the LICENSE file in the project root for more information. 
 
-#if !WINDOWS
+#if HAS_WPF
 using System.Reactive.Concurrency;
 using System.Windows.Threading;
 

+ 36 - 9
Rx.NET/Source/src/System.Reactive/Platforms/UWP/Concurrency/CoreDispatcherScheduler.cs

@@ -6,9 +6,11 @@
 using System.Reactive.Disposables;
 using System.Runtime.ExceptionServices;
 using System.Threading;
+using Windows.System;
 using Windows.UI.Core;
+#if HAS_OS_XAML
 using Windows.UI.Xaml;
-
+#endif
 namespace System.Reactive.Concurrency
 {
     /// <summary>
@@ -28,7 +30,7 @@ namespace System.Reactive.Concurrency
         public CoreDispatcherScheduler(CoreDispatcher dispatcher)
         {
             Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
-            Priority = CoreDispatcherPriority.Normal;
+            Priority = CoreDispatcherPriority.Normal;           
         }
 
         /// <summary>
@@ -50,7 +52,7 @@ namespace System.Reactive.Concurrency
         {
             get
             {
-                var window = Window.Current;
+                var window = CoreWindow.GetForCurrentThread();
                 if (window == null)
                 {
                     throw new InvalidOperationException(Strings_WindowsThreading.NO_WINDOW_CURRENT);
@@ -65,6 +67,8 @@ namespace System.Reactive.Concurrency
         /// </summary>
         public CoreDispatcher Dispatcher { get; }
 
+        private DispatcherQueue? _dispatcherQueue;
+
         /// <summary>
         /// Gets the priority at which work is scheduled.
         /// </summary>
@@ -108,10 +112,10 @@ namespace System.Reactive.Concurrency
                         // For scheduler implementation guidance rules, see TaskPoolScheduler.cs
                         // in System.Reactive.PlatformServices\Reactive\Concurrency.
                         //
-                        var timer = new DispatcherTimer
-                        {
-                            Interval = TimeSpan.Zero
-                        };
+                        
+                        var timer = CreateDispatcherQueue().CreateTimer();
+                        timer.Interval = TimeSpan.Zero;
+
                         timer.Tick += (o, e) =>
                         {
                             timer.Stop();
@@ -129,6 +133,28 @@ namespace System.Reactive.Concurrency
             );
         }
 
+        private DispatcherQueue CreateDispatcherQueue()
+        {
+            if(_dispatcherQueue != null)
+            {
+                return _dispatcherQueue;
+            }
+
+            if(Dispatcher.HasThreadAccess)
+            {
+                _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
+                return _dispatcherQueue;
+            }
+
+            // We're on a different thread, get it from the right one
+            Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
+            {
+                _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
+            }).GetAwaiter().GetResult(); // This is a synchronous call and we need the result to proceed
+
+            return _dispatcherQueue!;
+        }
+
         /// <summary>
         /// Schedules an action to be executed after <paramref name="dueTime"/> on the dispatcher, using a <see cref="DispatcherTimer"/> object.
         /// </summary>
@@ -158,7 +184,8 @@ namespace System.Reactive.Concurrency
         {
             var d = new MultipleAssignmentDisposable();
 
-            var timer = new DispatcherTimer();
+
+            var timer = CreateDispatcherQueue().CreateTimer();
 
             timer.Tick += (o, e) =>
             {
@@ -219,7 +246,7 @@ namespace System.Reactive.Concurrency
                 throw new ArgumentNullException(nameof(action));
             }
 
-            var timer = new DispatcherTimer();
+            var timer = CreateDispatcherQueue().CreateTimer();
 
             var state1 = state;
 

+ 20 - 14
Rx.NET/Source/src/System.Reactive/Platforms/UWP/Linq/CoreDispatcherObservable.cs

@@ -5,7 +5,10 @@
 #if WINDOWS
 using System.Reactive.Concurrency;
 using Windows.UI.Core;
+
+#if HAS_OS_XAML
 using Windows.UI.Xaml;
+#endif
 
 namespace System.Reactive.Linq
 {
@@ -13,7 +16,7 @@ namespace System.Reactive.Linq
     /// Provides a set of extension methods for scheduling actions performed through observable sequences on UI dispatchers.
     /// </summary>
     [CLSCompliant(false)]
-    public static class DispatcherObservable
+    public static class CoreDispatcherObservable
     {
         #region ObserveOn[Dispatcher]
 
@@ -64,6 +67,7 @@ namespace System.Reactive.Linq
             return Synchronization.ObserveOn(source, new CoreDispatcherScheduler(dispatcher, priority));
         }
 
+#if HAS_OS_XAML
         /// <summary>
         /// Wraps the source sequence in order to run its observer callbacks on the dispatcher associated with the specified object.
         /// </summary>
@@ -110,7 +114,7 @@ namespace System.Reactive.Linq
 
             return Synchronization.ObserveOn(source, new CoreDispatcherScheduler(dependencyObject.Dispatcher, priority));
         }
-
+#endif
         /// <summary>
         /// Wraps the source sequence in order to run its observer callbacks on the dispatcher associated with the current window.
         /// </summary>
@@ -118,7 +122,7 @@ namespace System.Reactive.Linq
         /// <param name="source">Source sequence.</param>
         /// <returns>The source sequence whose observations happen on the current window's dispatcher.</returns>
         /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
-        public static IObservable<TSource> ObserveOnDispatcher<TSource>(this IObservable<TSource> source)
+        public static IObservable<TSource> ObserveOnCoreDispatcher<TSource>(this IObservable<TSource> source)
         {
             if (source == null)
             {
@@ -146,9 +150,9 @@ namespace System.Reactive.Linq
             return Synchronization.ObserveOn(source, new CoreDispatcherScheduler(CoreDispatcherScheduler.Current.Dispatcher, priority));
         }
 
-        #endregion
+#endregion
 
-        #region SubscribeOn[Dispatcher]
+#region SubscribeOn[Dispatcher]
 
         /// <summary>
         /// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified dispatcher.
@@ -160,7 +164,7 @@ namespace System.Reactive.Linq
         /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="dispatcher"/> is null.</exception>
         /// <remarks>
         /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified dispatcher.
-        /// In order to invoke observer callbacks on the specified dispatcher, e.g. to render results in a control, use <see cref="DispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, CoreDispatcher)"/>.
+        /// In order to invoke observer callbacks on the specified dispatcher, e.g. to render results in a control, use <see cref="CoreDispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, CoreDispatcher)"/>.
         /// </remarks>
         public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, CoreDispatcher dispatcher)
         {
@@ -188,7 +192,7 @@ namespace System.Reactive.Linq
         /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="dispatcher"/> is null.</exception>
         /// <remarks>
         /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified dispatcher.
-        /// In order to invoke observer callbacks on the specified dispatcher, e.g. to render results in a control, use <see cref="DispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, CoreDispatcher, CoreDispatcherPriority)"/>.
+        /// In order to invoke observer callbacks on the specified dispatcher, e.g. to render results in a control, use <see cref="CoreDispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, CoreDispatcher, CoreDispatcherPriority)"/>.
         /// </remarks>
         public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, CoreDispatcher dispatcher, CoreDispatcherPriority priority)
         {
@@ -205,6 +209,7 @@ namespace System.Reactive.Linq
             return Synchronization.SubscribeOn(source, new CoreDispatcherScheduler(dispatcher, priority));
         }
 
+#if HAS_OS_XAML
         /// <summary>
         /// Wraps the source sequence in order to run its subscription and unsubscription logic on the dispatcher associated with the specified object.
         /// </summary>
@@ -215,7 +220,7 @@ namespace System.Reactive.Linq
         /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="dependencyObject"/> is null.</exception>
         /// <remarks>
         /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the dispatcher associated with the specified object.
-        /// In order to invoke observer callbacks on the dispatcher associated with the specified object, e.g. to render results in a control, use <see cref="DispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, DependencyObject)"/>.
+        /// In order to invoke observer callbacks on the dispatcher associated with the specified object, e.g. to render results in a control, use <see cref="CoreDispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, DependencyObject)"/>.
         /// </remarks>
         public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, DependencyObject dependencyObject)
         {
@@ -243,7 +248,7 @@ namespace System.Reactive.Linq
         /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="dependencyObject"/> is null.</exception>
         /// <remarks>
         /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the dispatcher associated with the specified object.
-        /// In order to invoke observer callbacks on the dispatcher associated with the specified object, e.g. to render results in a control, use <see cref="DispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, DependencyObject, CoreDispatcherPriority)"/>.
+        /// In order to invoke observer callbacks on the dispatcher associated with the specified object, e.g. to render results in a control, use <see cref="CoreDispatcherObservable.ObserveOn{TSource}(IObservable{TSource}, DependencyObject, CoreDispatcherPriority)"/>.
         /// </remarks>
         public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, DependencyObject dependencyObject, CoreDispatcherPriority priority)
         {
@@ -259,6 +264,7 @@ namespace System.Reactive.Linq
 
             return Synchronization.SubscribeOn(source, new CoreDispatcherScheduler(dependencyObject.Dispatcher, priority));
         }
+#endif
 
         /// <summary>
         /// Wraps the source sequence in order to run its subscription and unsubscription logic on the dispatcher associated with the current window.
@@ -269,9 +275,9 @@ namespace System.Reactive.Linq
         /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
         /// <remarks>
         /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the dispatcher associated with the current window.
-        /// In order to invoke observer callbacks on the dispatcher associated with the current window, e.g. to render results in a control, use <see cref="DispatcherObservable.ObserveOnDispatcher{TSource}(IObservable{TSource})"/>.
+        /// In order to invoke observer callbacks on the dispatcher associated with the current window, e.g. to render results in a control, use <see cref="CoreDispatcherObservable.ObserveOnCoreDispatcher{TSource}(IObservable{TSource})"/>.
         /// </remarks>
-        public static IObservable<TSource> SubscribeOnDispatcher<TSource>(this IObservable<TSource> source)
+        public static IObservable<TSource> SubscribeOnCoreDispatcher<TSource>(this IObservable<TSource> source)
         {
             if (source == null)
             {
@@ -291,7 +297,7 @@ namespace System.Reactive.Linq
         /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
         /// <remarks>
         /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the dispatcher associated with the current window.
-        /// In order to invoke observer callbacks on the dispatcher associated with the current window, e.g. to render results in a control, use <see cref="DispatcherObservable.ObserveOnDispatcher{TSource}(IObservable{TSource}, CoreDispatcherPriority)"/>.
+        /// In order to invoke observer callbacks on the dispatcher associated with the current window, e.g. to render results in a control, use <see cref="CoreDispatcherObservable.ObserveOnDispatcher{TSource}(IObservable{TSource}, CoreDispatcherPriority)"/>.
         /// </remarks>
         public static IObservable<TSource> SubscribeOnDispatcher<TSource>(this IObservable<TSource> source, CoreDispatcherPriority priority)
         {
@@ -303,7 +309,7 @@ namespace System.Reactive.Linq
             return Synchronization.SubscribeOn(source, new CoreDispatcherScheduler(CoreDispatcherScheduler.Current.Dispatcher, priority));
         }
 
-        #endregion
+#endregion
     }
 }
-#endif
+#endif

+ 16 - 18
Rx.NET/Source/src/System.Reactive/System.Reactive.csproj

@@ -1,18 +1,18 @@
 <Project Sdk="MSBuild.Sdk.Extras">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0;netstandard2.0;net46;uap10.0;uap10.0.16299</TargetFrameworks>
+    <TargetFrameworks>netcoreapp3.1;netstandard2.0;net46;uap10.0.16299;net5.0;net5.0-windows10.0.19041</TargetFrameworks>
     <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
     <PackageTags>Rx;Reactive;Extensions;Observable;LINQ;Events</PackageTags>
     <Description>Reactive Extensions (Rx) for .NET</Description>
   </PropertyGroup>
 
-  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
+  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1' or $(TargetFramework.StartsWith('net5.0-windows'))">
     <UseWPF>true</UseWPF>
     <UseWindowsForms>true</UseWindowsForms>
-    <IncludeBuildOutput>false</IncludeBuildOutput>
+    <IncludeBuildOutput Condition="'$(TargetFramework)' == 'netcoreapp3.1'">false</IncludeBuildOutput>
   </PropertyGroup>
 
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
+  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
     <FrameworkReference Update="Microsoft.WindowsDesktop.App" PrivateAssets="all" />
   </ItemGroup>
 
@@ -39,12 +39,12 @@
     <PackageReference Include="System.Dynamic.Runtime" Version="4.0.11" />
     <PackageReference Include="System.Linq.Queryable" Version="4.0.1" />
   </ItemGroup>
-  <ItemGroup Condition=" $(TargetFramework.StartsWith('uap10.0')) ">
+  <ItemGroup Condition=" $(TargetFramework.StartsWith('uap10.0')) or $(TargetFramework.StartsWith('net5.0-windows'))">
     <Compile Include="Platforms\UWP\**\*.cs" />
   </ItemGroup>
 
   <!-- Windows includes for Desktop and UWP -->
-  <ItemGroup Condition=" '$(TargetFramework)' == 'net46' or $(TargetFramework.StartsWith('uap10.0')) or '$(TargetFramework)' == 'netcoreapp3.0'">
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net46' or $(TargetFramework.StartsWith('uap10.0')) or '$(TargetFramework)' == 'netcoreapp3.1' or $(TargetFramework.StartsWith('net5.0-windows'))">
     <Compile Include="Platforms\Windows\**\*.cs" />
     <EmbeddedResource Include="Platforms\Windows\**\*.resx" />
   </ItemGroup>
@@ -57,7 +57,7 @@
     <Reference Include="WindowsBase" />
   </ItemGroup>
 
-  <ItemGroup Condition=" '$(TargetFramework)' == 'net46' or '$(TargetFramework)' == 'netcoreapp3.0'">
+  <ItemGroup Condition=" '$(TargetFramework)' == 'net46' or '$(TargetFramework)' == 'netcoreapp3.1' or $(TargetFramework.StartsWith('net5.0-windows'))">
     <Compile Include="Platforms\Desktop\**\*.cs" />
   </ItemGroup>
 
@@ -153,31 +153,29 @@
   </PropertyGroup>
 
   <!-- We remove the output from the nuget so it doesn't wind up in the \lib folder -->
-  <Target Name="RemoveNetCoreApp3FromNuGet" DependsOnTargets="BuiltProjectOutputGroup;DocumentationProjectOutputGroup" Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
+  <Target Name="RemoveNetCoreApp3FromNuGet" DependsOnTargets="BuiltProjectOutputGroup;DocumentationProjectOutputGroup" Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
     <ItemGroup>
       <!-- Before clearing the output groups, add them to None for packing -->
-      <ItemsToAddToNuGet Include="@(BuiltProjectOutputGroupOutput);@(DocumentationProjectOutputGroupOutput)" PackagePath="build\netcoreapp3.0" />
+      <ItemsToAddToNuGet Include="@(BuiltProjectOutputGroupOutput);@(DocumentationProjectOutputGroupOutput)" PackagePath="build\netcoreapp3.1" />
 
       <BuiltProjectOutputGroupOutput Remove="@(BuiltProjectOutputGroupOutput)" />
       <DocumentationProjectOutputGroupOutput Remove="@(DocumentationProjectOutputGroupOutput)" />
     </ItemGroup>
   </Target>
 
-  <Target Name="AddNetCore3ToNuGet" Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
+  <Target Name="AddNetCore3ToNuGet" Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
     <ItemGroup>
       <!-- Add the removed build output to the build\netcoreapp3.0 folder -->
-      <TfmSpecificPackageFileWithRecursiveDir Include="@(ItemsToAddToNuGet)" PackagePath="build\netcoreapp3.0" />
+      <TfmSpecificPackageFileWithRecursiveDir Include="@(ItemsToAddToNuGet)" PackagePath="build\netcoreapp3.1" />
     </ItemGroup>
   </Target>
 
   <ItemGroup>
-    <None Include="build\_._" PackagePath="lib\netcoreapp3.0" Pack="true" />
-    <None Include="build\System.Reactive.targets" PackagePath="buildTransitive\netcoreapp3.0" Pack="true" />
-    <None Include="build\System.Reactive.targets" PackagePath="build\netcoreapp3.0" Pack="true" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
+    <None Include="build\_._" PackagePath="lib\netcoreapp3.1" Pack="true" />
+    <None Include="build\_._" PackagePath="build\net5.0" Pack="true" />
+    <None Include="build\_._" PackagePath="buildTransitive\net5.0" Pack="true" />
+    <None Include="build\System.Reactive.targets" PackagePath="buildTransitive\netcoreapp3.1" Pack="true" />
+    <None Include="build\System.Reactive.targets" PackagePath="build\netcoreapp3.1" Pack="true" />
   </ItemGroup>
 
 </Project>

+ 1 - 1
Rx.NET/Source/src/System.Reactive/build/System.Reactive.targets

@@ -4,7 +4,7 @@
     <UseWindowsRxVersion Condition="'$(UseWindowsRxVersion)' == '' " >false</UseWindowsRxVersion>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Condition="'$(UseWindowsRxVersion)' == 'true' "  Include="$(MSBuildThisFileDirectory)..\..\build\netcoreapp3.0\System.Reactive.dll" />
+    <Reference Condition="'$(UseWindowsRxVersion)' == 'true' "  Include="$(MSBuildThisFileDirectory)..\..\build\netcoreapp3.1\System.Reactive.dll" />
     <Reference Condition="'$(UseWindowsRxVersion)' != 'true' "  Include="$(MSBuildThisFileDirectory)..\..\lib\netstandard2.0\System.Reactive.dll" />
 
     <FrameworkReference Include="Microsoft.WindowsDesktop.App" Condition="'$(UseWindowsRxVersion)' == 'true' and !@(FrameworkReference->AnyHaveMetadataValue('Identity', 'Microsoft.WindowsDesktop.App'))" />

+ 2 - 2
Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Tests.System.Reactive.ApiApprovals.csproj

@@ -8,8 +8,8 @@
   <ItemGroup>
     <Compile Remove="Api\*.verified.cs" />
     <Compile Remove="Api\*.received.cs" />
-    <None Include="Api\*.verified.cs" />
-    <None Include="Api\*.received.cs" />
+    <None Include="Api\*.verified.cs" Visible="true" />
+    <None Include="Api\*.received.cs" Visible="true" />
   </ItemGroup>
 
   <ItemGroup>

+ 1 - 1
Rx.NET/Source/tests/Tests.System.Reactive/DispatcherHelpers.cs

@@ -2,7 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT License.
 // See the LICENSE file in the project root for more information. 
 
-#if NETCOREAPP2_1 || NET46 || NETCOREAPP3_0
+#if NETCOREAPP2_1 || NET46 || NETCOREAPP3_1 || CSWINRT
 using System.Threading;
 #endif
 #if HAS_DISPATCHER

+ 2 - 2
Rx.NET/Source/tests/Tests.System.Reactive/Tests.System.Reactive.csproj

@@ -1,10 +1,10 @@
 <Project Sdk="MSBuild.Sdk.Extras">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0;net46;netcoreapp2.1</TargetFrameworks>
+    <TargetFrameworks>netcoreapp3.1;net46;netcoreapp2.1;net5.0;net5.0-windows10.0.19041</TargetFrameworks>
     <NoWarn>$(NoWarn);CS0618</NoWarn>
   </PropertyGroup>
 
-  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0' or '$(TargetFramework)' == 'net46'">
+  <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net46'">
     <UseWPF>true</UseWPF>
     <UseWindowsForms>true</UseWindowsForms>
   </PropertyGroup>

+ 7 - 7
Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/DispatcherSchedulerTest.cs

@@ -2,7 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT License.
 // See the LICENSE file in the project root for more information. 
 
-#if NET45
+#if HAS_WPF
 using System;
 using System.Diagnostics;
 using System.Reactive.Concurrency;
@@ -113,13 +113,11 @@ namespace ReactiveTests.Tests
             var id = Thread.CurrentThread.ManagedThreadId;
             var disp = DispatcherHelpers.EnsureDispatcher();
             var evt = new ManualResetEvent(false);
+
+            Exception thrownEx = null;
             disp.UnhandledException += (o, e) =>
             {
-#if NET45 || NET46
-                Assert.Same(ex, e.Exception); // CHECK
-#else
-                Assert.Same(ex, e.Exception.InnerException); // CHECK
-#endif
+                thrownEx = e.Exception;
                 evt.Set();
                 e.Handled = true;
             };
@@ -127,6 +125,8 @@ namespace ReactiveTests.Tests
             sch.Schedule(() => { throw ex; });
             evt.WaitOne();
             disp.InvokeShutdown();
+
+            Assert.Same(ex, thrownEx);
         }
 
         [Fact]
@@ -251,4 +251,4 @@ namespace ReactiveTests.Tests
         }
     }
 }
-#endif
+#endif

+ 2 - 2
Rx.NET/Source/version.json

@@ -1,7 +1,7 @@
 {
-  "version": "4.5.0-preview.{height}",
+  "version": "5.0.0-preview.{height}",
   "publicReleaseRefSpec": [
-    "^refs/heads/master$", // we release out of master
+    "^refs/heads/main$", // we release out of main
     "^refs/heads/rel/v\\d+\\.\\d+", // we also release branches starting with rel/vN.N
     "^refs/heads/rel/rx-v\\d+\\.\\d+" // we also release branches starting with rel/vN.N
   ],

+ 35 - 29
azure-pipelines.rx.yml

@@ -1,7 +1,7 @@
 trigger:
   branches:
     include:
-      - master
+      - main
       - rel/*
   paths:
     include:
@@ -12,7 +12,7 @@ trigger:
 pr:
   branches:
     include:
-    - master
+    - main
     - rel/*
   paths:
     include:
@@ -24,8 +24,7 @@ stages:
 - stage: Build
   jobs:
   - job: Build
-    pool:
-      vmImage: windows-2019
+    pool: vs2019-preview
 
     variables:
       BuildConfiguration: Release
@@ -34,9 +33,10 @@ stages:
 
     steps:
     - task: UseDotNet@2
-      displayName: Use .NET Core 3.1.x SDK
+      displayName: Use .NET Core 5.0.x SDK
       inputs:
-        version: 3.1.x
+        version: 5.0.x
+        includePreviewVersions: true
         performMultiLevelLookup: true
 
     - task: DotNetCoreCLI@2
@@ -70,26 +70,18 @@ stages:
         arguments: install --tool-path . dotnet-reportgenerator-globaltool
       displayName: Install ReportGenerator tool
 
-    - task: MSBuild@1
-      displayName: Build System.Reactive.sln
-      inputs:
-        solution: Rx.NET/Source/System.Reactive.sln
-        msbuildArguments: /t:rebuild /p:ContinuousIntegrationBuild=false
-        configuration: $(BuildConfiguration)
-        maximumCpuCount: false
-
     - task: DotNetCoreCLI@2
       inputs:
         command: test
         projects: Rx.NET/Source/tests/Tests.System.Reactive/*.csproj
-        arguments: -c $(BuildConfiguration) --no-build --no-restore --filter "SkipCI!=true" --settings Rx.NET/Source/CodeCoverage.runsettings --collect:"XPlat Code Coverage" -- RunConfiguration.DisableAppDomain=true
+        arguments: -c $(BuildConfiguration) --filter "SkipCI!=true" --settings Rx.NET/Source/CodeCoverage.runsettings --collect:"XPlat Code Coverage" -- RunConfiguration.DisableAppDomain=true
       displayName: Run Unit Tests
 
     - task: DotNetCoreCLI@2
       inputs:
         command: test
         projects: Rx.NET/Source/tests/Tests.System.Reactive.ApiApprovals/Tests.System.Reactive.ApiApprovals.csproj
-        arguments: -c $(BuildConfiguration) --no-build --no-restore
+        arguments: -c $(BuildConfiguration) 
       displayName: Run Api Approvals Tests
 
     - script: reportgenerator -reports:$(Agent.TempDirectory)/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/Rx.NET/Source/coverlet/reports -reporttypes:"Cobertura"
@@ -114,10 +106,11 @@ stages:
       artifact: ApprovalsTests
       condition: always()
 
-  - job: Integration_Linux_Tests
-    dependsOn: Build
+- stage: IntegrationTests
+  jobs:
+  - job: Linux
     pool:
-      vmImage: ubuntu-16.04
+      vmImage: ubuntu-latest
 
     variables:
       BuildConfiguration: Release
@@ -127,7 +120,13 @@ stages:
     steps:
     - task: UseDotNet@2
       inputs:
-        version: '3.0.x'
+        version: 5.0.x
+        includePreviewVersions: true
+
+    - task: UseDotNet@2
+      inputs:
+        version: '3.1.x'
+        packageType: runtime
 
     - task: UseDotNet@2
       inputs:
@@ -178,20 +177,26 @@ stages:
       inputs:
         command: test
         projects: $(System.DefaultWorkingDirectory)/Rx.NET/Integration/LinuxTests/LinuxTests.csproj
-        arguments: -c $(BuildConfiguration) -f netcoreapp3.0
-      displayName: Run 3.0 Tests on Linux
+        arguments: -c $(BuildConfiguration) -f net5.0 --filter "SkipCI!=true"
+      displayName: Run 5.0 Tests on Linux
 
     - task: DotNetCoreCLI@2
       inputs:
         command: test
         projects: $(System.DefaultWorkingDirectory)/Rx.NET/Integration/LinuxTests/LinuxTests.csproj
-        arguments: -c $(BuildConfiguration) --filter "SkipCI!=true" -f netcoreapp2.1 /p:TargetFrameworks=netcoreapp2.1
+        arguments: -c $(BuildConfiguration) -f netcoreapp3.1 --filter "SkipCI!=true"
+      displayName: Run 3.1 Tests on Linux
+
+    - task: DotNetCoreCLI@2
+      inputs:
+        command: test
+        projects: $(System.DefaultWorkingDirectory)/Rx.NET/Integration/LinuxTests/LinuxTests.csproj
+        arguments: -c $(BuildConfiguration) -f netcoreapp2.1 --filter "SkipCI!=true" 
       displayName: Run 2.1 Tests on Linux
 
-  - job: Integration_WindowsDesktop_Tests
-    dependsOn: Build
+  - job: WindowsDesktop    
     pool:
-      vmImage: windows-2019
+      vmImage: windows-latest
 
     variables:
       BuildConfiguration: Release
@@ -201,7 +206,8 @@ stages:
     steps:
     - task: UseDotNet@2
       inputs:
-        version: '3.0.x'
+        version: 5.0.x
+        includePreviewVersions: true
         performMultiLevelLookup: true
 
     - task: DotNetCoreCLI@2
@@ -249,10 +255,10 @@ stages:
         command: test
         projects: $(System.DefaultWorkingDirectory)/Rx.NET/Integration/WindowsDesktopTests/WindowsDesktopTests.csproj
         arguments: -c $(BuildConfiguration) --filter "SkipCI!=true"
-      displayName: Run 3.0 Tests on WindowDesktop
+      displayName: Run Tests on Window Desktop
 
 - stage: CodeSign
-  condition: and(succeeded('Build'), not(eq(variables['build.reason'], 'PullRequest')))
+  condition: and(succeeded('IntegrationTests'), not(eq(variables['build.reason'], 'PullRequest')))
   jobs:
   - deployment: CodeSign
     displayName: Code Signing