Async querying SQL in IIS let reply =  ref ""

let doAuto  =  
    async {
        let! resultAA =
            async { return SqlCmd.aaHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultBB =
            async { return SqlCmd.bbHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultCC =
            async { return SqlCmd.ccHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultDD =
            async { return SqlCmd.ddHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultEE =
            async { return SqlCmd.ddHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultFF =
            async { return SqlCmd.ffHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultGG =
            async { return SqlCmd.ggHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultHH =
            async { return SqlCmd.hhHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultII =
            async { return SqlCmd.iiHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultJJ =
            async { return SqlCmd.jjHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }
        let! resultKK =
            async { return SqlCmd.kkHits query |&gt; Async.RunSynchronously |&gt; List.ofSeq }

        let length1 = resultAA.Length + resultBB.Length

        if length1 &gt; 9 then reply := "hey " + length1.ToString()
        else
            let x = resultCC.Length + resultDD.Length + resultEE.Length + resultFF.Length + resultGG.Length 
                        + resultHH.Length + resultII.Length + resultJJ.Length + resultKK.Length + length1
            reply := x.ToString()

    } |&gt; Async.StartImmediate

!reply


The typical SqlCmd.xxHits (in module SqlCmd) built using FSharp.Data.SqlCommandTypeProvider looks like this:

[&lt;Literal&gt;]
let sqlXX = "SELECT ...@startsWith..."

type QueryXX = SqlCommand&lt;sqlXX, ConnectionStringName=...&gt;

let xxHits query = 
    let cmdXxHits = QueryXX(connectionString = connectionString, startsWith = query)
    cmdXxHits.AsyncExecute()


I'm pretty inexperienced at using async. Looking for feedback, especially in a couple of areas:


I couldn't think of a better way to get my results out from inside the outer async than the ref. From what I read it sounded like Async.StartImmediate was the best solution for something running in an IIS application. 
From the results of the first 2 inner asyncs, I may choose to quit before waiting for any more completions. Should I really be cancelling the remaining asyncs? Does it matter?
Avoid Async.RunSynchronously until absolutely necessary. It is very inefficient by design. Looks like you need:

async { let! xs = SqlCmd.xxxHits query
        return List.ofSeq xs }


Which you should probably abstract into a function.

Once you remove the blocking (RunSynchronously), the ref use also becomes invalid - you are querying the ref potentially before the async changes it - race condition. Try returning it (return) in the main async instead.

If you really want the subqueries to execute in parallel, consider a helper combinator like Async.Parallel rather than starting multiple sub-computations manually.

Your function should return Async&lt;string&gt; instead of string. If the caller of your code wants a string and cannot possibly use Async, they'll call Async.RunSynchronously - make it their problem.

Concerning choosing to quit based on the result of first two asyncs, not sure what you need exactly. Cancellation is an optimization - it may be tricky to get right but may make the code better performing. It's your decision based on the problem domain whether it is worth it or not.