F#程序在fsi中正确运行,但作为exe挂起

F#程序在fsi中正确运行,但作为exe挂起,f#,f#-interactive,F#,F# Interactive,我有一段代码,当MailboxProcessor接收到消息时,它会向数据库中添加一行。它在fsi中运行时工作正常,但在编译为exe时挂起。脚本如下: #r "../packages/Newtonsoft.Json/lib/net40/Newtonsoft.Json.dll" #r "../packages/SQLProvider/lib/FSharp.Data.SqlProvider.dll" open Newtonsoft.Json open FSharp.Data.Sql open Sys

我有一段代码,当
MailboxProcessor
接收到消息时,它会向数据库中添加一行。它在fsi中运行时工作正常,但在编译为exe时挂起。脚本如下:

#r "../packages/Newtonsoft.Json/lib/net40/Newtonsoft.Json.dll"
#r "../packages/SQLProvider/lib/FSharp.Data.SqlProvider.dll"

open Newtonsoft.Json
open FSharp.Data.Sql
open System

let [<Literal>] ResolutionPath = __SOURCE_DIRECTORY__ + "/../build/" 
let [<Literal>] ConnectionString = "Data Source=" + __SOURCE_DIRECTORY__ + @"/test.db;Version=3"

// test.db is initialized as follows:
//
// BEGIN TRANSACTION;
//    CREATE TABLE "Events" (
//        `id`INTEGER PRIMARY KEY AUTOINCREMENT,
//        `timestamp` DATETIME NOT NULL
//    );
//    COMMIT;

type Sql = SqlDataProvider< 
            ConnectionString = ConnectionString,
            DatabaseVendor = Common.DatabaseProviderTypes.SQLITE,
            ResolutionPath = ResolutionPath,
            IndividualsAmount = 1000,
            UseOptionTypes = true >
let ctx = Sql.GetDataContext()

let agent = MailboxProcessor.Start(fun (inbox:MailboxProcessor<String>) ->  
    let rec loop() =
        async {
            let! msg = inbox.Receive()
            match msg with
            | _ ->
              let row = ctx.Main.Events.Create()
              row.Timestamp <- DateTime.Now
              printfn "Submitting"
              ctx.SubmitUpdates()
              printfn "Submitted"
            return! loop() 
        }
    loop() 
)

agent.Post "Hello"
#r.。/packages/Newtonsoft.Json/lib/net40/Newtonsoft.Json.dll
#r.“./packages/SQLProvider/lib/FSharp.Data.SQLProvider.dll”
打开Newtonsoft.Json
打开FSharp.Data.Sql
开放系统
让[]ResolutionPath=\uuuuu源目录\uuuuu+“/../build/”
let[]ConnectionString=“Data Source=“+\uuuuuu Source\u DIRECTORY\uuuuu+@”/test.db;Version=3”
//test.db初始化如下:
//
//开始交易;
//创建表“事件”(
//`id`整数主键自动递增,
//`timestamp`DATETIME不为空
//    );
//承诺;
类型Sql=SqlDataProvider<
ConnectionString=ConnectionString,
DatabaseVendor=Common.DatabaseProviderTypes.SQLITE,
ResolutionPath=ResolutionPath,
单个Samount=1000,
UseOptionTypes=true>
设ctx=Sql.GetDataContext()
让代理=MailboxProcessor.Start(乐趣(收件箱:MailboxProcessor)->
让rec循环()=
异步的{
let!msg=inbox.Receive()
配味精
| _ ->
让row=ctx.Main.Events.Create()

row.Timestamp问题似乎是主线程在
MailboxProcessor
处理其邮箱之前退出。FSI是长期存在的,因此不会在那里发生这种情况。我更改了:

[<EntryPoint>]
let main argv =
    agent.Post "Hello"
    agent.Post "Hello again"
    0
[]
让主argv=
探员,发“你好”
探员,再发一次“你好”
0

[]
让主argv=
探员,发“你好”
探员,再发一次“你好”
让waitLoop=async{
当agent.CurrentQueueLength>0时
打印fn“睡眠”
do!Async.Sleep 1000
}
Async.RunSynchronously waitLoop
0

现在代码按照我的预期执行。

我不确定它挂起的确切原因,但我可以告诉你,你误用了
ctx
。数据上下文应该是“短暂的”——即为每个自包含的操作重新创建并立即销毁。但你在整个过程中使用的是单个上下文。
[<EntryPoint>]
let main argv =
    agent.Post "Hello"
    agent.Post "Hello again"
    let waitLoop = async {
        while agent.CurrentQueueLength > 0 do
            printfn "Sleeping"
            do! Async.Sleep 1000
        }
    Async.RunSynchronously waitLoop
    0