3

我想从 HttpListener 的 Owin 实现中使用此方法:

public static IDisposable Create(AppFunc app, IDictionary<string, object> properties)

AppFunc 有这样的签名:

IDictionnary<string,Object> -> Task

我想创建一个任务,但它需要一个动作,我不知道如何在 F# 中执行它。到目前为止,我管理的最好的方法是使用这个问题中的代码:

module CsharpAction

open System

type Wrapper<'T>(f:'T -> unit) =
      member x.Invoke(a:'T) = f a

let makeAction (typ:Type) (f:'T -> unit) = 
    let actionType = typedefof<Action<_>>.MakeGenericType(typ)
    let wrapperType = typedefof<Wrapper<_>>.MakeGenericType(typ)
    let wrapped = Wrapper<_>(f)
    Delegate.CreateDelegate(actionType, wrapped, wrapped.GetType().GetMethod("Invoke"))

程序.fs

let yymmdd1 (date:DateTime) = date.ToString("yy.MM.dd")
    let printSuccess = fun() -> printfn "Success %s" (yymmdd1 DateTime.Now )
    let actionTask = CsharpAction.makeAction (typeof<string>) (printSuccess)
    let mutable properties = Dictionary(dict [("fooKey", new Object())])


    let server = OwinServerFactory.Create((fun (props) -> new  Task(actionTask)) , properties)

但后来它告诉我:这个表达式应该有类型动作,但这里有类型委托

我应该从 F# 对 c# 代码执行操作吗?或者我应该处理 c# 代码以便给 f# 一些细节,例如等待委托而不是操作?

我正在与我的知识极限调情,我确实感到痛苦。很肯定,我必须学习很多东西,但如果你能帮我爬上第一步……

4

1 回答 1

10

您不需要使用反射在 F# 中创建委托。您可以完全放弃代码的第一部分(您的CsharpAction模块)。

至于第二段代码,试试这个:

open System
open System.Collections.Generic
open System.Threading.Tasks

let yymmdd1 (date : DateTime) = date.ToString "yy.MM.dd"
let printSuccess () = printfn "Success %s" (yymmdd1 DateTime.Now)

let server =
    let actionTask = Action printSuccess
    let properties = Dictionary (dict ["fooKey", obj ()])
    OwinServerFactory.Create((fun props -> new Task (actionTask)), properties)
于 2013-09-14T13:54:32.263 回答