I have in my test solution 3 projects:
In the class library I define an akka.net actor:
namespace Just.Test.Project
open Akka.Actor
open Akka.FSharp
open Akka.Configuration
module Actors =
let system = System.create "WaveNetSystem" (Configuration.defaultConfig())
let simple = spawn system "simple" (fun mailbox ->
let rec loop() = actor {
let! message = mailbox.Receive()
printfn "%A" message
return! loop()
}
loop()
)
type MainClass(msg) = let x = Actors.simple <! msg
If I instantiate the MainClass
from f# console application, I get expected result:
[<EntryPoint>]
let main argv =
Just.Test.Project.MainClass("bugaga!") |> ignore
System.Threading.Thread.Sleep(1000)
0 // return an integer exit code
output:
"bugaga!!!"
But. If I do the same from c# console app:
static void Main(string[] args)
{
new Just.Test.Project.MainClass("bugaga!");
System.Threading.Thread.Sleep(1000);
}
I get an exception:
System.TypeInitializationException: The type initializer for '<StartupCode$SampleFSharpAkkaNet>.$Test' threw an exception. ---> System.MissingMethodException: Method not found: 'Akka.Actor.IActorRef Akka.FSharp.Spawn.spawn(Akka.Actor.IActorRefFactory, System.String, Microsoft.FSharp.Core.FSharpFunc`2<Actor`1<!!0>,Cont`2<!!0,!!1>>)'.
at <StartupCode$SampleFSharpAkkaNet>.$Test..cctor()
--- End of inner exception stack trace ---
at Just.Test.Project.Actors.get_simple()
at Just.Test.Project.MainClass..ctor() in d:\prj\research\AkkaFSharpTest\SampleFSharpAkkaNet\Test.fs:line 20
How should I interpret this exception? What might be wrong?
UPDATE
As already noted in comments and in Tomas Petricek answer, the issue is related to the version mismatch. The bindingRedirect
does the job and everything starts working. But I still have some misunderstanding.
First. The Akka.FSharp
references FSharp.Core 4.3.1
.
Second. The F#Lib and F#Console references FSharp.Core 4.4.0
and C#Console has no references to FSharp.Core
at all.
Third. The F#Console works like a charm and if I print loaded assemblies I get:
FSharpConsole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
FSharpLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Akka, Version=1.0.6.16, Culture=neutral, PublicKeyToken=null
Akka.FSharp, Version=1.0.6.16, Culture=neutral, PublicKeyToken=null
FsPickler, Version=1.2.21.0, Culture=neutral, PublicKeyToken=null
System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
so, no FSharp.Core 4.3.1.0
loaded and everything is tip-top!
Fourth. The C#Console does not work. The list of loaded assemblies looks a bit strange:
CSharpConsole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
FSharpLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Akka, Version=1.0.6.16, Culture=neutral, PublicKeyToken=null
Akka.FSharp, Version=1.0.6.16, Culture=neutral, PublicKeyToken=null
It means both FSharp.Core, Version=4.4.0.0
and FSharp.Core, Version=4.3.1.0
are loaded. Why? And why it does not happened in F#Console case?
SOLUTION
The problem (as usually )) was in my head.
First of all, I never looked into the final F#Console config. The initial app.config
is quite simple:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
but after the build it gets (thanks to AutoGenerateBindingRedirects MSBuild flag ) the required buinding redirects:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
The second one. C# compiler was trying to notify me about the problem by writing such messages in the build output:
No way to resolve conflict between "FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" and "FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". Choosing "FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" arbitrarily. Consider app.config remapping of assembly "FSharp.Core, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" from Version "4.3.1.0" [C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\FSharp.NETFramework\\v4.0\\4.3.1.0\\FSharp.Core.dll] to Version "4.4.0.0" [C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\FSharp.NETFramework\\v4.0\\4.4.0.0\\FSharp.Core.dll] to solve conflict and get rid of warning. C:\\Program Files (x86)\\MSBuild\\14.0\\bin\\Microsoft.Common.CurrentVersion.targets(1820,5): warning MSB3276: Found conflicts between different versions of the same dependent assembly. Please set the "AutoGenerateBindingRedirects" property to true in the project file. For more information, see http://go.microsoft.com/fwlink/?LinkId=294190 .
But I decided that C# compiler is just a little more restrictive as F# compiler. I didn't know that in F# projects the flag is set automatically. What stoped me from checking it? I do not know! )
This sounds like an FSharp.Core.dll
version mismatch issue.
Most likely, you are referencing a newer version of FSharp.Core.dll
than the one that has been referenced by the F# wrapper library for Akka.net. You can either reference the same version, or add a config file with bindingRedirect
. See Mark Seemann's blog post .
The keyword here is MethodMissingException
- you are getting that because the signature of the method involves types from FSharp.Core.dll
and the version that has been loaded (based on the reference in the C# project) does not match the version exposed by the wrapper (based on the reference used when compiling the wrapper). Because of the version mismatch, the types are treated as different and "method is not found".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.