使用异步并行迭代进行F#类型初始化异常

时间:2015-12-16 00:48:25

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

我收到错误" File.exe中发生类型初始化异常; File.Mod2的类型初始值设定项引发了异常。"但是,例外的断点是在Mod1中 - 顺便说一下,没有声明任何内容,在Locals窗口中没有任何内容,没有任何东西可以调试....

我认为这可能与我是在一个模块中声明类型SqlDataConnection还是在每个模块中单独声明,或者我是否在每个模块中的一个模块中全局分配db.GetDataContext,在每个模块中都需要它,或在一个功能,然后传递它/周围。但移动声明并没有帮助。 (我在过去很少得到这个错误,并且它有点固定。我忘了,它是如此罕见,要么我会继续。或者我会重新开始,而不是在运行时触摸SQL Server。)

此代码工作数周,可以一次运行几天并上传500M +结果。我一直在修改,但我不认为我碰到了类型提供程序或数据库部分中的任何内容。

最后一点:我可以确切地指出在一些侦探工作之后抛出异常的位置。如上所述,调试器在Mod1中的一行上中断了异常。但是,如果我完成迭代,那么在" IDList |>中完成第一个ID后,中断就会发生。在Mod2中的List.iter(有趣的ID - > GetDataLists ID |> IterateParams ID paramLists)"。在Mod4中的最后一个UpLoad结果之后发生中断,此时代码应该返回到Mod2以获取下一个ID,而是在第一个最抽象的调用中在Mod1中中断。最后,请注意错误消息说Mod2中引发了异常 - 即使break在Mod1中。 (而且我无法从Mod4步进到Mod2来检查异常情况 - 它从Mod4跳转到Mod1。)

编辑***我错了一个细节。中断不会从Mod4跳转到Mod1。 Mod4确实返回到Mod2。如果我仔细步骤,Flow将从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

1 个答案:

答案 0 :(得分:0)

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

我应该删除这整个烂摊子。我等了几个小时,然后寻找一个标志。