7

所以,我有一个想要在事件触发器上执行的函数,但我想稍后将其删除。我该怎么做?我知道 F# 事件具有Add将函数添加为处理程序的方法,但您不能删除此函数。我明白,但我根本找不到如何创建任何委托!(嗯,有type Foo = delegate of type1 -> type2我不明白它的用法......)

编辑:这是我想要做的一个更清楚的例子,在代码中:

// Define and publish event
let _someEvent = new Event<string>()
let SomeEvent = someEvent.Publish

// Normally, I'd do this to use it:
SomeEvent.Add (fun arg -> printfn "Argument: %s" arg)

// Trigger the event
someEvent.Trigger "Hello world"

但我的问题是我想在某个时候删除这个钩子。我知道它可能与代表......只是不知道该怎么做。

4

3 回答 3

7

另一种选择是使用订阅方法并使用 Dispose 取消订阅:

// Define and publish event
let someEvent = new Event<string>()
let SomeEvent = someEvent.Publish

// Subscribe to event
let subscription =
    SomeEvent.Subscribe (fun arg -> printfn "Argument: %s" arg)

// Trigger the event
someEvent.Trigger "Hello world"

// Unsubscribe
subscription.Dispose()
于 2013-02-01T07:21:16.840 回答
6

是的,只需使用处理程序。

// Define and publish event
let _someEvent = new Event<string>()
let SomeEvent = _someEvent.Publish

// wrap function in handler
let handler = Handler<string>(fun _ arg -> printfn "Argument: %s" arg)

// add
SomeEvent.AddHandler handler

// remove
SomeEvent.RemoveHandler handler
于 2013-01-26T07:51:13.060 回答
3

您可以像创建任何其他对象一样在 F# 中创建委托。只需将一个函数传递给它的构造函数。您还可以像在任何 .Net 语言中一样,使用 .Net 语言从事件中删除处理程序RemoveHandler。您需要确保将最初添加的委托传递给它。

此示例(您可以在 FSI 中运行)创建一个PaintEventHandler填充蓝色表单的表单,并将其添加到表单的Paint事件中。然后将窗体上的按钮设置为从事件中删除绘制处理程序,并强制重绘窗体。

open System
open System.Drawing
open System.Windows.Forms

let form = new Form()

let paintHandler =
    PaintEventHandler( // The function is passed to the delegate constructor.
        fun sender e ->
            e.Graphics.Clear Color.CornflowerBlue
    )

form.Paint.AddHandler paintHandler // Handler added.

let btn = new Button()
btn.Text <- "Remove Handler"
btn.Width <- 200;
btn.Click.Add (fun e ->
    form.Paint.RemoveHandler paintHandler // Handler removed.
    form.Invalidate() // Redraw
)
form.Controls.Add btn

form.Show()

重要的是要注意AddHandler/RemoveHandler采用普通委托,但Add采用不同签名的功能。(sender缺少参数。)

于 2013-01-26T04:09:26.810 回答