Skip to content

Commit

Permalink
Fix #1785 CancellationToken.Register
Browse files Browse the repository at this point in the history
  • Loading branch information
alfonsogarciacaro committed Mar 12, 2019
1 parent 2e5de24 commit e782bb4
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/Fable.Transforms/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2371,6 +2371,7 @@ let cancels (_: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr optio
Helper.CoreCall("Async", Naming.removeGetSetPrefix i.CompiledName |> Naming.lowerFirst, t, args, argTypes, ?loc=r) |> Some
// TODO: Add check so CancellationTokenSource cannot be cancelled after disposed?
| "Dispose" -> Null Type.Unit |> makeValue r |> Some
| "Register" -> Helper.InstanceCall(thisArg.Value, "register", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| _ -> None

let monitor (_: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
Expand Down
5 changes: 5 additions & 0 deletions src/fable-library/AsyncBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export class CancellationToken {
removeListener(id: number) {
return this._listeners.delete(id);
}
register(f: (state?: any)=>void, state?: any) {
const $ = this;
const id = this.addListener(state == null ? f : () => f(state));
return { Dispose() { $.removeListener(id); } }
}
}

export class OperationCanceledError extends Error {
Expand Down
24 changes: 19 additions & 5 deletions tests/Main/AsyncTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ type Get =
| GetZero of replyChannel: AsyncReplyChannel<int>
| GetOne of replyChannel: AsyncReplyChannel<int>

let sleepAndAssign token res =
Async.StartImmediate(async {
do! Async.Sleep 200
res := true
}, token)

let tests =
testList "Async" [
testCase "Simple async translates without exception" <| fun () ->
Expand Down Expand Up @@ -112,11 +118,6 @@ let tests =
#if FABLE_COMPILER
testCaseAsync "Async cancellation works" <| fun () ->
async {
let sleepAndAssign token res =
Async.StartImmediate(async {
do! Async.Sleep 200
res := true
}, token)
let res1, res2, res3 = ref false, ref false, ref false
let tcs1 = new System.Threading.CancellationTokenSource(50)
let tcs2 = new System.Threading.CancellationTokenSource()
Expand All @@ -131,6 +132,19 @@ let tests =
equal false !res2
equal true !res3
}

testCaseAsync "CancellationTokenSource.Register works" <| fun () ->
async {
let mutable x = 0
let res1 = ref false
let tcs1 = new System.Threading.CancellationTokenSource(50)
let foo = tcs1.Token.Register(fun () ->
x <- x + 1)
sleepAndAssign tcs1.Token res1
do! Async.Sleep 500
equal false !res1
equal 1 x
}
#endif

testCase "Async.StartWithContinuations works" <| fun () ->
Expand Down

0 comments on commit e782bb4

Please sign in to comment.