dotnet / dotnet/reactive

Weird UWP reference in unexpected places

Open
#1,059 8 comments 3 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
7.2k
Forks
798
PR merge metrics
No merged PRs in 30d

Description

# The symptom

We ran into an interesting bug (?) recently, while updating our services to .NET Core we suddenly started receiving strange build errors, like:

`The type 'IAsyncAction' is defined in an assembly that is not referenced. You must add a reference to assembly 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime'.`

`The type 'IAsyncActionWithProgress<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime'.`

`The type 'IAsyncOperation<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime'.`

`The type 'IAsyncOperationWithProgress<,>' is defined in an assembly that is not referenced. You must add a reference to assembly 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime'.`

These errors were pointing to lines where we directly `await`ed `IObservable`s, like
```csharp
await Observable.Return("Hello World");
```

# The clue

As I've been rigorously scanning through our dependencies and project file definitions, one thing stood out, that the `System.Reactive` NuGet package has a reference to `System.Runtime.InteropServices.WindowsRuntime` for `netstandard2.0` target. ( [link](https://github.com/dotnet/reactive/blob/9bb3b15bc318b20a91d7440da74d89c525325487/Rx.NET/Source/src/System.Reactive/System.Reactive.csproj#L32) ).

This on its own though is not causing any immediate trouble...

# The realization

I created a clean project with reference to Rx and tried to `await` an `IObservable`... and it worked just fine, so I figured, the issue will be somewhere else... So I started stripping down the dependencies from our original project, until it finally built successfully.

And then I found that because we migrated to .NET Core, we no longer had implicit access to certain Windows specific APIs, so we referenced `Microsoft.Windows.Compatibility` and by doing that we must have activated a special scenario for Rx's platform services, or something where it started to try to be WinRT compatible and give us those errors when trying to `await` on an `IObservable`.

# The solution

The solution was to either reference the more specific compatibility packages, like `System.Configuration.ConfigurationManager` and `System.ServiceProcess.ServiceController` and/or to explicitly use the `ToTask()` extension method before attempting to `await` an `IObservable`.

# The question

With all this, I'm still a little confused about why Rx has reference to WinRT Interop package for its .NET Standard (cross platform) target? I'd guess this weird issue would never have came up in the first place if it wouldn't have that reference.

# Repro

csproj file
```xml


Exe
netcoreapp3.0




```

Program.cs
```csharp
using System;
using System.Reactive.Linq;
using System.Threading.Tasks;

namespace Repro
{
class Program
{
static async Task Main(string[] args)
{
await Observable.Return("Hello World");
}
}
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.