我想从Owin实现的HttpListener中使用这个方法:
public static IDisposable Create(AppFunc app, IDictionary<string, object> properties)
Run Code Online (Sandbox Code Playgroud)
AppFunc有这样的签名:
IDictionnary<string,Object> -> Task
Run Code Online (Sandbox Code Playgroud)
我想创建一个任务,但它需要一个动作,我不知道如何在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"))
Run Code Online (Sandbox Code Playgroud)
program.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)
Run Code Online (Sandbox Code Playgroud)
但它告诉我:这个表达式应该有类型动作,但这里有类型委托
我应该从F#向c#代码提供一个动作吗?或者我应该使用c#代码来为f#提供一些细节,例如等待委托代替行动?
我正在调整我的知识极限,我确实感受到了痛苦.很确定,我将不得不学到很多东西,但如果你能帮我爬第一步......
您不需要使用反射来在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)
Run Code Online (Sandbox Code Playgroud)