问题(其中3个相关)在下面以粗体显示。
我正在尝试创建一个F#类 - 我需要使用它而不从C#引用F#的程序集。
我有这样的代码:
type ReceiverExceptionEventArgs(ex:Exception) =
inherit EventArgs()
member this.Exception = ex
type ExceptionRaised = delegate of obj * ReceiverExceptionEventArgs -> unit
type Receiver( ... ) =
let error = new Event<ExceptionRaised, ReceiverExceptionEventArgs>()
let a = new Actor<...>(fun inbox -> ...)
[<CLIEvent>]
member __.Error = error.Publish
/// Starts the receiver which starts the consuming from the service bus
/// and creates the queue if it doesn't exist
member x.Start () =
logger.InfoFormat("start called for queue '{0}'", desc)
a.Post Start
我想在let a = new Actor...
之后添加此内容:
do a.Error.Add(fun ex -> error.Trigger(this, new ReceiverExceptionEventArgs(ex)))
但我在上面的行中没有提及'this'...我怎样才能在F#中以惯用方式进行?
作为进一步的复杂化, actor正在启动许多基本上是循环的异步计算;这些计算返回单位,所以我不能这样做:
let startPairsAsync pairs token =
async {
for Pair(mf, rs) in pairs do
for r in rs do
match Async.Start(Async.Catch(r |> worker), token) with
| Choice1Of2 () -> ()
| Choice2Of2 ex -> error.Trigger(null, new ReceiverExceptionEventArgs(ex)) }
因为worker r
是Async<unit>
,所以我在第一次模式匹配时得到This expression was expected to have type 'unit' but was here 'Choice1of2<'a, 'b>'
。
题外话:
我是否也为每个工人创建演员?我想要的代码类似于erlang的“主管”,因为我正在使用的代码几乎可以在任何时候(网络)任意失败......主管不在这个问题的范围内;但是我会使用mutliple Actors而不是Async.Catch获得更好的惯用异常处理吗?
答案 0 :(得分:4)
关于this
,请使用
type MyClass(args) as this =
在构造函数中绑定this
的声明中的。 (您可以使用任何您喜欢的标识符。)
(另见
http://lorgonblog.wordpress.com/2009/02/13/the-basic-syntax-of-f-classes-interfaces-and-members/
)
答案 1 :(得分:2)
关于涉及异步工作流的第二个问题,我并不完全理解你的代码,但是如果你试图启动一些异步计算并处理执行它们时可能发生的异常,那么使用它会容易得多{{ 1}}在异步工作流内而不是try ... with
。这样的事情可能会更好:
Async.Catch