在C#WebJob中,我可以像这样手动调用公共静态类方法:

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;

namespace foo
{
    public class Program
    {

        [NoAutomaticTrigger]
        public static void Go(TraceWriter log) { ... }

        static void Main()
        {
           var host = new JobHost();
           var methodInfo = typeof(Program).GetMethod("Go");
           host.Call(methodInfo);
           host.RunAndBlock();
        }

methodInfo是一个System.Reflection.MethodInfo,在调试器中我可以看到它具有Attributes Public | Static | HideBySig和CustomAttributes Microsoft.Azure.WebJobs.NoAutomaticTriggerAttribute

我正在尝试在F#中执行此操作。这是我到目前为止的内容:
type Foo() =

    [<NoAutomaticTrigger>]
    static member Go (log:TraceWriter) =
        log.Info "hello!"

[<EntryPoint>]
let main argv =
        let theType = typedefof<Foo>
        let methodInfo = theType.GetMethods() |> Seq.find(fun t -> t.Name = "Go")
        host.Call(methodInfo)
        host.RunAndBlock()

WebJobs运行时不喜欢它:
System.InvalidOperationException
  HResult=0x80131509
  Message='Void Go(Microsoft.Azure.WebJobs.Host.TraceWriter)' can't be invoked from Azure WebJobs SDK. Is it missing Azure WebJobs SDK attributes?
  Source=Microsoft.Azure.WebJobs.Host
  StackTrace:
   at Microsoft.Azure.WebJobs.JobHost.Validate(IFunctionDefinition function, Object key)
   at Microsoft.Azure.WebJobs.JobHost.<CallAsyncCore>d__37.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.JobHost.Call(MethodInfo method)
   at Program.main(String[] argv) in C:\path\to\project\Program.fs:line 110

我的F#methodInfo确实具有NoAutomaticTrigger属性。它还具有Public和Static,但是缺少HideBySig。这可能很重要吗?我应该比较MethodInfos的其他部分吗?

以下是来自webjobs sdk的相关资源:https://github.com/Azure/azure-webjobs-sdk/blob/v2.2.0/src/Microsoft.Azure.WebJobs.Host/JobHost.cs#L306

对于它的价值,我已经能够成功地使用F#中的TimerTrigger和ServiceBusTrigger。我正在努力的只是这种手动调用模式。

接下来,我打算筛选一下webjobs的源代码,并试图弄清楚它到底在寻找什么,但是我希望有一些对F#和/或webjobs更有经验的人可以告诉我。

最佳答案

通过WebJobs源码进行调试后,我最终对
DefaultTypeLocator,它拾取标记为IsPublic的类。我尝试了F#声明,但似乎无法实现;我只设法产生了IsNestedPublic

因此,我尝试了另一种方法:我没有尝试编写现有WebJobs运行时可发现的F#函数,而是覆盖了发现逻辑:

type myTypeLocator() =
    interface ITypeLocator with
        member this.GetTypes () =
            new System.Collections.Generic.List<Type>([ typedefof<Foo> ]) :> IReadOnlyList<Type>

...
let config = new JobHostConfiguration (
                    DashboardConnectionString = dashboardConnectionString,
                    StorageConnectionString = storageConnectionString,
                    TypeLocator = new myTypeLocator()
                )

let host = new JobHost(config)

这行得通:我的功能被发现,我能够JobHost.Call他们。

关于.net - 如何在F#中声明可以通过WebJob的JobHost.CallAsync调用的函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50706730/

10-16 20:33