Skip to content

F# Invoke Timer doesn't work due to reflection w/ System.Threading.Tasks.Task #585

@LukePammant

Description

@LukePammant

Expected Behavior

I should be able to register a Timer in an F# Actor and have it call the appropriate method.

Actual Behavior

The dotnet sdk throws an error on ValidateTimerCallback.

The first error occurs on Actor.cs ln:335 is:
Timer callback method: {callback} does not exist in the Actor class: {actorTypeName}
This can be worked around by prefixing the method name (callback argument) with "get_". For example the Tick method must be registered to the timer as get_Tick.

The second error is when validating that the return type is a Task. Even if the method just returns Task.CompletedTask this line will throw an error saying that the return type is not a task.

When I inspect the ReturnType while debugging I see that the F# Task is: Microsoft.FSharp.Core.FSharpFunc``2[[Microsoft.FSharp.Core.Unit, FSharp.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.Threading.Tasks.Task, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], FSharp.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

If I remove the Validation function I run into an exception on this line when it tries to cast the method call into a Task:

The tick method can be invoked via the dotnet sdk without issues via:
(POST {{daprUrl}}/v1.0/actors/MyActor/myactorid/method/Tick)

Maybe the dotnet sdk can fall back to calling the method the same way the InvokeMethod does without trying to cast the method to a Task?
DispatchInternalAsync does work when invoking the method
DispatchWithoutRemoting

Steps to Reproduce the Problem

From an F# actor call the Start method:
(POST {{daprUrl}}/v1.0/actors/MyActor/myactorid/method/Start)
member this.Start() = task { do! this.RegisterTimerAsync( "Tick", "get_Tick", null, TimeSpan.FromMilliseconds(float 1000), TimeSpan.FromMilliseconds(float 1000) ) |> Async.AwaitTask |> Async.Ignore } :> Task

The tick method can be:
member this.Tick() = Task.CompletedTask

Release Note

RELEASE NOTE:

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is neededkind/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions