Could not load file or assembly 'System.Interactive.Async, Version=3.0.1000.0, ...'

1,465 views
Skip to first unread message

janos....@sonarsource.com

unread,
Apr 19, 2017, 10:30:21 AM4/19/17
to grpc.io
Hi,

I'm having an issue with client-side streaming in C#. When my client code in a VSIX package tries to call a service that returns a stream, I get the following exception:

An exception of type 'System.IO.FileNotFoundException' occurred in Grpc.Core.dll but was not handled in user code

Additional information: Could not load file or assembly 'System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263' or one of its dependencies. The system cannot find the file specified.

The version number is suspiciously 3.0.1000.0 instead of 3.0.3000.0. I noticed that the project references version 3.0.3000.0. This reference got added automatically when I used nuget manager to add grpc. On the other hand, grpc.core seems to depend on 3.0.1000.0. 

These lines were automatically added in my app.config, and I thought it's supposed to prevent the issue I'm having, but sadly that's not the case:

      <dependentAssembly>
        <assemblyIdentity name="System.Interactive.Async" publicKeyToken="94bc3704cddfc263" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" />
      </dependentAssembly>

The same client works fine with simple RPC, only streaming RPC causes a problem. (More specifically, I call an endpoint that takes a simple input and returns a stream.)

For a sanity check, I created a dummy Class Library project, but there I don't get the same issue, streaming RPC works just fine. My real target is a VSIX project, net46.

How can I make this work in a VSIX project? Or, is there a way to consume a streaming output without using System.Interactive.Async? Although ultimately I would like to be able to consume a stream asynchronously, synchronous mode could be acceptable in the short term.

Thank you,
Janos

janos....@sonarsource.com

unread,
Apr 21, 2017, 2:56:28 AM4/21/17
to grpc.io, janos....@sonarsource.com
This was resolved.

The binding redirect *is* the solution, but in case of a VSIX, the configuration in app.config won't be used. This is because in case of a VSIX, the main executable is not the VSIX, but Visual Studio. One way to configure binding redirects in this case is to write AssemblyInfo.cs of the VSIX like this:

using Microsoft.VisualStudio.Shell;
using System.Reflection;

[assembly: AssemblyTitle("the-project-name.Vsix")]
[assembly: ProvideBindingRedirection(AssemblyName = "System.Interactive.Async", NewVersion = "3.0.3000.0",
    OldVersionLowerBound = "0.0.0.0", OldVersionUpperBound = "3.0.3000.0")]

Another issue that I didn't see at the time, but equally important, is that the native libraries are not automatically included in the VSIX, and will also raise a runtime error. One way to fix that is to include this in the .csproj file of the VSIX:

  <Target Name="IncludeDllsVsix" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <Grpc_Regex>grpc_csharp_ext.*\.dll</Grpc_Regex>
    </PropertyGroup>
    <ItemGroup>
      <Content Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Content.Identity)', '$(Grpc_Regex)'))">
        <IncludeInVSIX>True</IncludeInVSIX>
      </Content>
    </ItemGroup>
  </Target>

Cheers,
Janos
Reply all
Reply to author
Forward
0 new messages