Scott Nimrod
Scott Nimrod

Reputation: 11595

How to write a Task.ContinueWith within an Async computation expression

I'm struggling to figure out how to write a Task.ContinueWith within a Async computation expression.

Ultimately, I want to process a cancel without relying on the Cancel Exception. As a result, I thought I could use Task.ContinueWith.

However, I'm in-over-my-head on trying to write this.

Any suggestions?

let rec receiveXmlMessage connection (cancellation:CancellationToken) queue =

    async {

        use receiveCommand = new SqlCommand(receiveQuery, connection, CommandTimeout = 0)
        let result = receiveCommand.ExecuteNonQueryAsync(cancellation)

        result.ContinueWith(fun (someResult:Task<int>) -> CancellableResult.Cancelled // IDK... ) |> AsyncResult.fromAsync
    }

Error Type mismatch. Expecting a Task> -> 'b but given a Async<'c> -> Async> The type 'Task>' does not match the type 'Async<'b>'

Upvotes: 1

Views: 373

Answers (1)

kvb
kvb

Reputation: 55184

Sorry, this isn't necessarily an answer but wouldn't fit well as a comment.

Do you need to pass a cancellation token to your workflow? I think it might be better to use Async.CancellationToken to propagate the workflow's existing token:

async {
    let! ct = Async.CancellationToken // gets the async workflow's current cancellation token
    use receiveCommand = new SqlCommand(receiveQuery, connection, CommandTimeout = 0)
    let! result = receiveCommand.ExecuteNonQueryAsync(ct) |> Async.AwaitTask
    // do something with the result
}

By threading the async workflow's cancellation token through to the computation you care about, you enable cancelling the workflow to do the right thing - it can cancel the top-level workflow when transitioning from one step to another, or it can cancel the query execution if that's what's executing.

Then when you schedule your async via a method like Async.RunSynchronously or Async.Start you can pass in an existing cancellation token if you have one.

However, it's not completely clear to me if this is what you're actually trying to do, since you're using let rec but you haven't indicated any need for recursive logic.

Upvotes: 2

Related Questions