我想将现有的事件实现替换为可以在必要时同时处理事件的事件。不幸的是我之前从未实现过任何类型的并发,但必须从某个地方开始呃?
我一直在阅读Functional Reactive Programming。尽管看起来相对简单,但我对如何将这些示例应用到我的应用程序中感到困惑。事实上,我甚至不确定这是否是最适合实现并发的方法。
我还能以某种方式利用任务并行库(TPL),因为它提供了线程管理,那么我不需要过多担心产生太多线程。遗憾的是,上述链接中的示例不包含使用TPL的任何内容。
我目前的代码如下。我仍然是一个新手程序员,需要一些手握才能通过。为麻烦道歉。 :(
open System
open System.Threading
open Npgsql
// This application is a Windows service. PostgreSQL sends a notice whenever a new row has been added to a table.
// The next function processes new rows, aka tasks.
let private processTask () =
EventLog.writeEventLog "Information" "Received new task notification."
// Task processing yet to be implemented.
// A connection to PostgreSQL that stays open while service is running. Receives notifications.
let newNotifyConnection (host : string, username : string, password : string, database : string) =
let connectionString = sprintf "Host=%s;Username=%s;Password=%s;Database=%s;ContinuousProcessing=true;Keepalive=120;CommandTimeout=0" host username password database
new NpgsqlConnection(connectionString)
let private notifyConnection = newNotifyConnection Settings.npgsqlConnection
let private listen = new NpgsqlCommand("LISTEN newtask", notifyConnection)
// Event for receiving and processing notifications.
let private onNotification (sender : obj) (e : NpgsqlNotificationEventArgs) =
processTask()
let private notificationEventHandler = new NotificationEventHandler(onNotification)
// Run this function when service starts.
let startWorker () =
notifyConnection.Notification.AddHandler(notificationEventHandler)
notifyConnection.Open()
listen.ExecuteNonQuery() |> ignore
// Run this function when service stops.
let stopWorker () =
listen.Dispose()
notifyConnection.Dispose()
答案 0 :(得分:2)
如果您愿意首先使用F#进行功能编程路线而且我建议安装可从Nuget获得的FSharp.Control.Reactive。这将使得使用RX变得更加容易,包括向Observable模块添加更多方法(默认情况下,F#只包含一个子集)。
对我来说,代码中的关键方法如下所示,因为这是将回调链接到事件源的方法。
let startWorker () =
notifyConnection.Notification.AddHandler(notificationEventHandler)
notifyConnection.Open()
listen.ExecuteNonQuery() |> ignore
诀窍是给你的notifyConnection对象一个回调对象,RX为你提供了在Npgsql库和RX框架之间桥接世界的可能性。
类似的东西:
open System
open System.Reactive.Linq
let observableCreate subscriptionFunction = Observable.Create(new Func<_, IDisposable>(subscriptionFunction))
let sourceObservable = observableCreate (fun observer ->
// Your notifyConnection object will now direct all events to the observer provided
notifyConnection.Notification.AddHandler(observer.OnNext)
notifyConnection.Open()
listen.ExecuteNonQuery() |> ignore
// RX includes the CompositeDisposable class which you can also use
{ new IDisposable with
x.Dispose() =
listen.Dispose()
notifyConnection.Dispose() })
use subscription = sourceObservable.Subscribe(notifyConnectionHandler)
请注意,FSharp.Control.Reactive Nuget包提供了Observable.create函数。 (编辑:已经指出Reactive包没有Observable.Create的包装器所以我自己定义了它)。
以上将(订阅时 - 使用Subscribe()方法): - 打开连接 - 执行查询 - 创建一个在处理订阅时使用的一次性用品。
更有趣的是,您可以使用Observable模块中的方法链接observable并将其与其他人组合,从而允许您创建被动程序。如果你有兴趣在F#中使用IEvent的/ IObservable,那么读RX可能是明智的。