【问题标题】:F# Type Initialization Exception with Async Parallel iteration异步并行迭代的 F# 类型初始化异常
【发布时间】:2015-12-16 00:48:24
【问题描述】:

我收到错误“File.exe 中发生类型初始化异常;File.Mod2 的类型初始化程序引发异常。”然而,异常的断点在 Mod1 中——顺便说一句,这里没有声明任何内容,Locals 窗口中没有任何内容,也没有要调试的内容......。

我认为这可能与我是在一个模块中声明类型 SqlDataConnection 还是在每个模块中单独声明类型有关,或者我是否在一个模块、每个模块、每个需要的函数中或在一个模块中全局分配 db.GetDataContext函数,然后将其向上传递/传递。但是移动声明并没有帮助。 (过去我很少遇到此错误,但它会自行修复。我忘记了,这太罕见了,我会点击继续。或者我会重新开始,并且在运行时不接触 SQL Server。)

此代码运行了数周,一次可以运行数天并上传 5 亿多条结果。我一直在修改,但我认为我没有触及 Type Provider 或数据库部分中的任何内容。

最后一点:我可以精确定位在迭代中,在进行了一些侦探工作之后引发异常的确切位置。如前所述,调试器在 Mod1 中的一行出现异常中断。但是,如果我遍历迭代,则在 Mod2 中“IDList |> List.iter (fun ID -> GetDataLists ID |> IterateParams ID paramLists)”中的第一个 ID 完成后中断。中断发生在 Mod4 中的最后一个 UpLoad 结果之后,此时代码应返回到 Mod2 以获取下一个 ID,但改为在 Mod1 中中断,即第一个最抽象的调用。最后,请注意错误消息表明异常是在 Mod2 中引发的——即使中断是在 Mod1 中。 (而且我不能从 Mod4 跳到 Mod2 来检查异常条件——它会从 Mod4 跳到 Mod1。)

编辑*** 我弄错了一个细节。中断不会从 Mod4 跳转到 Mod1。 Mod4 确实返回到 Mod2。如果我小心翼翼,流程会从 Mod4 中的最后一次上传(成功)返回到 Mod2 中的 AsyncSeries。然后从 Mod2 中的 AsyncSeries 下一步是到 Mod1 中的一行。

这里是抽象代码,只是为了说明流程,并附有异常注释。

namespace MyNameSpace

module Mod4 =  //type provider is used here
    let UpLoadOneResult ID result = ... //****Last result of 1st ID uploads. 
                    //Exception then in Mod1--instead of iterating in Mod2. 
    let UploadResults ID resultsList = 
        resultsList |> List.iter (fun r -> UploadOneResult ID r)


module Mod3 = //type provider is used here
    let rec SolveResults ID kList mList rev resultList (x, y, z, w) = ...
        SolveResults ID kList.Tail mList.Tail newResultList (x, y, z, w)        


module Mod2 =
        type dbSchema1 = Microsoft.FSharp.Data.TypeProviders.
        SqlDataConnection<"Data Source=DESKTOP-55M3AJ5\SQLEXPRESS;
        Initial Catalog=Data;Integrated Security=True;
        MultipleActiveResultSets=True;">   
        //I omit this from example modules above, but they do have 
        //dbSchema2, etc. 

    let GetParamLists = ...  //this func just hard coded. my user interface for now.
        (xList, yList, zList, wList)

    let GetDataLists ID = 
        let db1 = dbSchema1.GetDataContext()    // "use"? "new"? () as argument? 
        let kList = query { for row in db1.Data ... } |> Seq.toList 
        let mList = query { for row in db1.Data ... } |> Seq.toList 
        (kList, mList)

    let IterateParams ID (xList, yList, zList, wList) (kList, mList) =   

        let MakeParamCombos xList yList zList wList =
            [for x in xList do
             for y in yList do 
             for z in zList do
             for w in wList do
             yield (x, y, z, w)]

        let AsyncSeries (x, y, z, w) = async { 
            return  SolveResults ID kList mList [] (x, y, z, w)        
            |> UpLdResults ID   }

        MakeParamCombos xList yList zList wList
        |> List.map AsyncSeries
        |> Async.Parallel 
        |> Async.RunSynchronously
        |> ignore


    let CalcResults  =   
        let db1 = dbSchema1.GetDataContext()
        let paramLists = GetParamLists
        let IDList = query { for row in db1.Data ... } |> Seq.toList
        IDList |> List.iter (fun ID -> GetDataLists ID |> IterateParams ID paramLists ) 
        //*** the first ID run completes. Code fails to return here for 2nd ID. 
        ()


module Mod1 =
    [<EntryPoint>] 
    let main argv =
        CalcResults |> ignore    //**ERROR point, on second iteration of "IDList |> List.iter ... "
        0

【问题讨论】:

  • 在 Mod2 中,在决定性的“IDList |> List.iter”中,IDlist 以 int list 类型给出,GetDataLists 的参数是 int 类型。当我在第一次通过时在这里休息时,IDList 在 Locals 窗口中看起来不错。
  • Big "hmmmm" 这里:如果我注释掉定义 IDList 的查询并硬编码一个 ID 列表: 1. 它在类似 [4; 6; 10个; 12]。但它在 [1; 2; 3; 4]。并且 ID 1 也是查询中的第一个,导致中断。所以我想这可能是数据中的一些奇怪的东西。但是由于这个异常的性质是跳转到错误的模块,而在 Locals 中什么都没有——这就像 1980 年代的调试,或者更糟,现在。
  • 但是,如果在声明 SQL 数据连接类型和 GetDataContext 分配的位置方面有任何最佳实践可遵循——这可能会有所帮助,并且在任何情况下都会非常感激。
  • 仅供参考:ID 1 的最后一行,之后发生异常是“db3.DataContext.ExecuteCommand(@"INSERT INTO Data.dbo. ...”,在 Mod4 中。让我确认这条线实际上是成功还是失败。它在“try”块中,“with | exn -> ()”。
  • 现在我看到了我草率错过的 Mod2 的回归,也许我可以从那里的当地人那里得到一些东西。

标签: asynchronous parallel-processing f# type-providers typeinitializeexception


【解决方案1】:

看起来问题只是在我的一个新编辑中,我在将 List.Head 放在一个我得到一个 ID 为 2 的空列表的地方(在 ID 1 之后...... )。所以这个问题有点疯狂。这个错误是微不足道的。但这并不是(只是)我完全是个白痴:在我的流程中,无论出于何种原因,这个基本错误都会导致难以理解的异常和异常环境。并且:不仅仅是我从来没有想过要单步执行代码。相反,当我试图单步执行时,错误会跳到我前面——除非我在代码的每一行都设置了一个断点,然后用 F11 单步执行。

我可能应该删除这整个混乱。我会等几个小时,然后再寻找一个迹象。

【讨论】:

  • 好吧,我可以一夜之间运行而不会再次出现错误。有点,或者几乎没有。也就是说,我的代码运行没有错误——但在晚上的某个时候,MSFT 决定更新 Win 10 比运行 sims 更重要——对于我的 g/d 工作。所以他们重新启动了我一小部分的方式。太好了。谢谢。
猜你喜欢
  • 2012-09-07
  • 2012-07-07
  • 2013-04-03
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 2011-04-16
相关资源
最近更新 更多